package org.codehaus.groovy.tools;

import java.io.*;
import groovy.util.XmlSlurper;
import groovy.xml.StreamingMarkupBuilder;

class FailsGenerator {

    def public conf;
    def public map = new HashMap();
    def public save=false
    public boolean hasChanged=false
    public int nr=0;
    public boolean skipIgnores=true
    
    public FailsGenerator(){}    

    static void main(args) {
        if (args.length<2) {
            println "usage: FailsGenerator [--save] [--skip-ignores] <conf-file> <reports-dir>"
            println "         save           is optional argument and let the script store the results"
            println "                        found in the xml files in the conf file"
            println "         skip-ignores   don't print information about ignored files "
            println "         conf-file      is the configuration file"
            println "         reports-dir    is the directory containing the xml reports from JUnit"
            System.exit(1)
        }
        def gen = new FailsGenerator();
        int argIndex=0
        while (args[argIndex].startsWith("--")) {
          switch (args[argIndex]) {
            case "--save":
              gen.save=true
              break;
            case "--skip-ignores":
              gen.skipIgnores=true
              break;
            default:
              println "unknown option "+ args[argIndex]
              System.exit(1);
          }
          argIndex++;
        }
        gen.conf = new File(args[argIndex])
        gen.readConf()
        gen.compareFiles(args[argIndex+1])
        gen.saveConf()
        println "DONE"
    }
    
    
    void compareFiles(dir) {
    
        def attReader = { name, attName, oldVal, newVal ->
            if (attName!=null) oldVal=Integer.parseInt(oldVal)
            boolean success = (oldVal!=0 && newVal==0)
            if (success) {
                println("${name}: well done, no more ${attName}");
            } else if (oldVal==-1) {
                // do nothing
            } else if (newVal<oldVal) {
                println("${name}: improved ${attName} from ${oldVal} to ${newVal}");
            } else if (newVal>oldVal) {
                println("${name}: more ${attName} (from ${oldVal} to ${newVal})");
            }
            hasChanged = hasChanged || newVal!=oldVal
            return success
        }


        dir = new File(dir)
        if (!dir.isDirectory()) throw new RuntimeException("${dir} has to be a directory containg the xml tests reports")
        dir.eachFileRecurse {
            file ->
            if (!file.getName().endsWith(".xml")) return
            if (file.getName().indexOf("\$")>-1) {
              if (!skipIgnores) println("${file.name} is ignored because it's output for a subclass")
              return
            }
            def node = new XmlSlurper().parse(file);
            def name = node['@name']
            def errorVal = Integer.parseInt(node['@errors'])
            def failureVal = Integer.parseInt(node['@failures'])

            def el = map.get(name)
            if (el==null && !save) throw new RuntimeException("unknown test ${name}, please add it to conf file ${conf.name}")
            if (el==null && save) {
                el = new HashMap()
                el.put("errors","-1");
                el.put("failures","-1");
                println "added configuration for test ${name}"
                addToMap(name,el)
                hasChanged=true
            }

            def err  = attReader(name,"errors",el.errors,errorVal)
            def fail = attReader(name,"failures",el.failures,failureVal)
            if (err && fail) {
                println(">>> Congratulations ${name} has passed the test <<<");
            }
            el.errors = errorVal
            el.failures = failureVal
        }
    }        
    
    void saveConf() {
        if (!save) return
        if (!hasChanged) {
            println "no changes to configuration"
            return
        }
        println "saving conf in ${conf}, old configuration is saved in ${conf}.old"
        println "WARNING: comments are not in the new file"
        def oldConf = new File(conf.absolutePath+".old")
        def bytes = conf.readBytes()
        def out = oldConf.newOutputStream()
        out << bytes
        out.close()
        out = conf.newWriter()
        try {
            map.each {
                 out.writeLine("[${it.key}]")
                 it.value.each {
                     out.writeLine("${it.key}=${it.value}")
                 }
            }
        } finally {
            out.close();
        }
    }

    void readConf() {
        def reader = new LineNumberReader(new FileReader(conf));
        def line = null;

        def readLine = {l ->
            if (l!=null) return l
            while (true) {
                l = reader.readLine()
                if (l==null) return null
                if (""==l) continue
                l=l.trim()
                if (l[0] == "#") continue
                return l
            }
        }

        def lineloop = {l,lbreak,func ->
            while(true) {
                if (l!=null && lbreak) return l
                if (l==null) l = readLine(l)
                if (l==null) return
                nr= reader.lineNumber;
                l = func(l)
            }
            return l
        }

        def attRead = {el,l->
            l = lineloop(l,true) {ll ->
                if (ll[0]=="[" || ll[-1]=="]") return ll
                int index = ll.indexOf('=');
                if (index==-1) throw new RuntimeException(" ${conf.name}:${nr} = expected somewhere, but got ${ll}");
                String name = ll.substring(0,index).trim();
                String value = "";
                if (ll.length()>=index) value = ll.substring(index+1).trim();
                el.put(name,value);
                return null
            }
            return l
        }


        def fileStart = {->
            lineloop(null,false) {l ->
                if (l[0]!="[" || l[-1]!="]") {
                    throw new RuntimeException("${conf.name}:${nr} filename inside of [] expected, but got ${line}")
                }
                def el = new HashMap()
                def file = line.substring(1,l.length()-1)
                addToMap(file,el);
                l = attRead(el,null)
                return l
            }
        }
        
        try {
            fileStart()
        } finally {
            reader.close();
        }
        if (map.size==0) throw new RuntimeException("${conf.name} was empty");
    }
    
    def addToMap(name, el) {
        map.put(name,el)
    }

    
}

