package metalexer.jflex;
import java.io.IOException;
import java.util.*;

import metalexer.*;
import metalexer.ast.Layout;

public class ML2JFlex {
    public static void main(String[] args) {
        int firstArg = 0;
        boolean tracing = false;
        if(args.length > 0 && args[0].equals("-t")) {
            tracing = true;
            firstArg++;
        }
        if(args.length - firstArg != 3) {
            System.err.println("Usage: java ML2JFlex [-t] {layout} {indir1;indir2;...} {outdir}");
            System.exit(1);
        }
        String basename = args[firstArg + 0];
        String inpath = args[firstArg + 1];
        String outdir = args[firstArg + 2];
        System.out.println("Checking " + basename + " in " + inpath);
        SortedSet<CompilationProblem> problems = new TreeSet<CompilationProblem>();
        Layout layout = null;
        try {
            List<String> dirs = new ArrayList<String>();
            StringTokenizer tokenizer = new StringTokenizer(inpath, ";");
            while(tokenizer.hasMoreTokens()) {
                dirs.add(tokenizer.nextToken());
            }
            FileLoader loader = new FileLoader(dirs);
            layout = loader.loadLayout(basename, problems);
            if(layout == null) {
                problems.add(layout.makeCompilationError(layout.getName() + " not found."));
            } else {
                layout = layout.processInheritance(loader, problems);
                if(layout.getHelper()) {
                    problems.add(layout.makeCompilationError(layout.getName() + " is a helper layout."));
                }
            }
        } catch(IOException e) {
            problems.add(new CompilationError(null, e.getMessage()));
        }
        SortedSet<CompilationWarning> warnings = ProblemUtil.extractWarnings(problems);
        for(CompilationWarning warning : warnings) {
            System.out.println(warning);
        }
        SortedSet<CompilationError> errors = ProblemUtil.extractErrors(problems);
        if(errors.isEmpty()) {
            System.out.println("VALID");
            try {
                layout.tidyRuleGroups();
                layout.deleteUnusedDeclarations();
                layout.assignCharsToMetaTokens(new metalexer.jflex.CharacterAssigner(new metalexer.jflex.CharacterGenerator()));
                layout.setTracingCodeEmbedded(tracing);
                layout.generateJFlex(outdir);
                layout.generateMetaJFlex(outdir);
            } catch (IOException e) {
                System.out.println(new CompilationError(null, e.getMessage()));
            }
        } else {
            for(CompilationError error : errors) {
                System.out.println(error);
            }
        }
    }
}
