package org.datacite.mds.validation.constraints.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.datacite.mds.util.DomainUtils;
import org.datacite.mds.util.ValidationUtils;
import org.datacite.mds.validation.constraints.Symbol;
import org.datacite.mds.validation.constraints.Symbol.Type;

public class SymbolValidator implements ConstraintValidator<Symbol, String> {

    List<Type> types;
    boolean hasToExist;
    
    static final HashMap<Type, Pattern> PATTERNS = new HashMap<Type, Pattern>() {
        {
            String symbol = "[A-Z][A-Z\\-]{0,6}[A-Z]"; 
            put(Type.ALLOCATOR, Pattern.compile(symbol));
            put(Type.DATACENTRE, Pattern.compile(symbol + "\\." + symbol));
        }
    };
    
    public void initialize(Symbol constraintAnnotation) {
        types = Arrays.asList(constraintAnnotation.value());
        hasToExist = constraintAnnotation.hasToExist();
    }

    public boolean isValid(String symbol, ConstraintValidatorContext context) {
        // TODO check if required
        context.disableDefaultConstraintViolation();
        if (symbol == null) 
            return true;
        
        if (isMalformed(symbol, context))
            return false;
        
        if (hasToExist) 
            return exists(symbol, context);
        
        return true;
    }

    boolean isMalformed(String symbol, ConstraintValidatorContext context) {
        for (Type t : types) {
            if (PATTERNS.get(t).matcher(symbol).matches() && symbol.indexOf("--") == -1) {
                //check against the pattern for each given type 
                return false;
            } else {
                String message = "{org.datacite.mds.validation.constraints.Symbol." + t.name() + ".message}";
                ValidationUtils.addConstraintViolation(context, message);
            }
        }
        return true;
    }

    boolean exists(String symbol, ConstraintValidatorContext context) {
        boolean foundSymbol = DomainUtils.findAllocatorOrDatacentreBySymbol(symbol) != null;
        if (foundSymbol) 
            return true;

        ValidationUtils.addConstraintViolation(context, "{org.datacite.mds.validation.constraints.Symbol.notfound}");
        return false;
    }
}

@@ -48,16 +48,44 @@
 .impl;%0A%0A
+import java.util.ArrayList;%0A
 import j
@@ -610,20 +610,16 @@
 oExist;%0A
-    
 %0A    sta
@@ -757,17 +757,16 @@
 %7D%5BA-Z%5D%22;
- 
 %0A       
@@ -909,20 +909,16 @@
 %0A    %7D;%0A
-    
 %0A    pub
@@ -1286,17 +1286,16 @@
 == null)
- 
 %0A       
@@ -1312,24 +1312,16 @@
 n true;%0A
-        
 %0A       
@@ -1381,24 +1381,16 @@
  false;%0A
-        
 %0A       
@@ -1405,17 +1405,16 @@
 ToExist)
- 
 %0A       
@@ -1450,24 +1450,16 @@
 ntext);%0A
-        
 %0A       
@@ -1548,32 +1548,98 @@
 text context) %7B%0A
+        List%3CString%3E violationMessages = new ArrayList%3CString%3E();%0A
         for (Typ
@@ -1762,16 +1762,17 @@
       //
+ 
 check ag
@@ -1808,17 +1808,16 @@
 ven type
- 
 %0A       
@@ -1880,25 +1880,30 @@
     
-String message = 
+violationMessages.add(
 %22%7Bor
@@ -1973,22 +1973,92 @@
 essage%7D%22
+)
 ;%0A    
+        %7D%0A        %7D%0A        for (String message : violationMessages)%0A
         
@@ -2123,32 +2123,8 @@
 e);%0A
-            %7D%0A        %7D%0A
     
@@ -2336,17 +2336,16 @@
 dSymbol)
- 
 %0A       

fix issue with wrong error message shown