package dr.xml;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Check {

    private static final Pattern doublePattern = Pattern.compile("[-]*\\d*\\.\\d+|\\d+\\.\\d*$");



    public Check(Report report, String[] regexes, String[] values) {
        String stringReport = getReportAsString(report);
        for (String expression: regexes){
            String stringValue = parseDoubleRegex(stringReport, expression);
        }
        //TODO: parse regexes & values
        //TODO: make comparisons
    }

    private String getReportAsString(Report report){

        StringWriter sWriter = new StringWriter();
        PrintWriter pWriter = new PrintWriter(sWriter);
        report.setOutput(pWriter);

        report.createReport();

        return sWriter.toString();

    }

    private String parseDoubleRegex(String report, String matchBase){
        String match = "\n" + matchBase + ":";
        int lastInd = report.lastIndexOf(match);
        if (lastInd == -1){
            throw new RuntimeException("Did not find \"" + matchBase + "\" in the report.");
        }
        Matcher matcher = doublePattern.matcher(report);
        matcher.find(lastInd);
        int sInd = matcher.start();
        int lInd = matcher.end();
        int stringLength = lInd - sInd;
        char[] doubleChars = new char[stringLength];
        report.getChars(sInd, lInd, doubleChars, 0);
        String doubleString = new String(doubleChars);

        return doubleString;
    }



    private static final String CHECK = "check";
    private static final String REGEX = "regex";
    private static final String MATCH = "match";


    public static AbstractXMLObjectParser PARSER = new AbstractXMLObjectParser() {
        @Override
        public Object parseXMLObject(XMLObject xo) throws XMLParseException {
            Report report = (Report) xo.getChild(Report.class);


            List<XMLObject> matches = xo.getAllChildren(MATCH);
            int nMatch = matches.size();
            String[] regexes = new String[nMatch];
            String[] values = new String[nMatch];
            for (int i = 0; i < nMatch; i++){
                XMLObject match = matches.get(i);
                regexes[i] = (String) match.getAttribute(REGEX);
                values[i] = match.getStringChild(0);
            }

            return new Check(report, regexes, values);
        }

        @Override
        public XMLSyntaxRule[] getSyntaxRules() {
            return rules;
        }



        @Override
        public String getParserDescription() {
            return null;
        }

        @Override
        public Class getReturnType() {
            return null;
        }

        @Override
        public String getParserName() {
            return CHECK;
        }
    };

    private final static XMLSyntaxRule[] rules = new XMLSyntaxRule[]{
            new ElementRule(Report.class),
            new ElementRule(MATCH, new XMLSyntaxRule[]{
                    AttributeRule.newStringRule(REGEX)
            }, 1, Integer.MAX_VALUE)};
    };



@@ -264,16 +264,49 @@
 %5Cd*$%22);%0A
+    private final Report report;%0A
 %0A%0A%0A    p
@@ -368,16 +368,47 @@
 alues) %7B
+%0A%0A        this.report = report;
 %0A       
@@ -448,25 +448,20 @@
 sString(
-report
 );%0A
+%0A
         
@@ -469,34 +469,42 @@
 or (
-String expression: regexes
+int i= 0; i %3C regexes.length; i ++
 )%7B%0A 
@@ -570,18 +570,18 @@
 rt, 
-expression
+regexes%5Bi%5D
 );%0A 
@@ -591,48 +591,111 @@
     
-%7D%0A        //TODO: parse regexes &
+    if (!stringValue.equals(values%5Bi%5D))%7B%0A                failCheck(regexes%5Bi%5D, stringValue,
  values
+%5Bi%5D);
 %0A   
@@ -703,32 +703,278 @@
     
-//TODO: make comparisons
+    %7D%0A        %7D%0A%0A    %7D%0A%0A    private void failCheck(String name, String reportValue, String trueValue)%7B%0A        System.out.println(%22Report returned %22 + reportValue + %22 for %22 + name + %22.%22%0A                + %22 The true value is %22 + trueValue + %22.%22);%0A        System.exit(-1);
 %0A   
@@ -1014,29 +1014,16 @@
 sString(
-Report report
 )%7B%0A%0A    

check compares string values