package infrastructure;

import infrastructure.json.JsonElement;
import infrastructure.json.JsonStructure;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author Lucas
 */
public class SemanticListener {
    
    protected JsonStructure root;
    protected List<String>  errors;
    protected boolean       validate;

    public SemanticListener(JsonStructure _root) {
        root     = _root;
        errors   = new LinkedList<>();
        validate = false;
    }

    public boolean isValid() {
        Validate();
        return errors.isEmpty();
    }
    
    public LinkedList<String> Validate() {
        if (!validate) {
            validate = true;
        
            // does validation over root
            RuleOnlyOneField();
        }
        
        return new LinkedList<>(errors);
    }

    
    protected boolean RuleOnlyOneField() {
        return RuleOnlyOneField(root);
    }
    
    protected boolean RuleOnlyOneField(JsonStructure node) {

        boolean hasErrors = false;
        List<JsonElement> innerElements = new LinkedList<>(node.values);
        
        while(!innerElements.isEmpty()) {
            JsonElement pivot = innerElements.get(0);
            
            int i = 1;
            while (i < innerElements.size()) {
                JsonElement current = innerElements.get(i);
                
                if (pivot.name.toLowerCase().equals(current.name.toLowerCase())) {
                    hasErrors = true;
                    errors.add("Semantic error: redeclaration of field \"" + pivot.name + "\".");
                    innerElements.remove(i);
                } else {
                    i++;
                }
            }
        }

        return !hasErrors;
    }
    
    protected boolean RuleProductsPricesAndTaxesMatchTotal(JsonStructure node) {
        return false;
    }
}

@@ -522,15 +522,17 @@
 ean 
-isValid
+hasErrors
 () %7B
@@ -541,16 +541,24 @@
         
+return !
 Validate
@@ -563,40 +563,93 @@
 te()
+.isEmpty()
 ;%0D%0A    
+%7D%0D%0A
     
-return errors.isEmpty
+%0D%0A    public List%3CString%3E errors() %7B%0D%0A        return Validate
 ();%0D
@@ -673,22 +673,16 @@
  public 
-Linked
 List%3CStr
@@ -836,16 +836,26 @@
 OneField
+OfEachType
 ();%0D%0A   
@@ -967,16 +967,26 @@
 OneField
+OfEachType
 () %7B%0D%0A  
@@ -1014,16 +1014,26 @@
 OneField
+OfEachType
 (root);%0D
@@ -1084,16 +1084,26 @@
 OneField
+OfEachType
 (JsonStr
@@ -1662,40 +1662,11 @@
 dd(%22
-Semantic error: redeclaration of
+The
  fie
@@ -1690,16 +1690,42 @@
 me + %22%5C%22
+ has already been declared
 .%22);%0D%0A  
@@ -1846,32 +1846,84 @@
 %0A            %7D%0D%0A
+            %0D%0A            innerElements.remove(0);%0D%0A
         %7D%0D%0A%0D%0A   

Update SemanticListener