package metalexer.jflex;
import java.io.IOException;
import java.util.SortedSet;
import java.util.TreeSet;

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

public class ML2JFlex {
    public static void main(String[] args) {
        if (args.length != 3) {
            System.err.println("Usage: java ML2JFlex {layout} {indir} {outdir}");
            System.exit(1);
        }
        String basename = args[0];
        String indir = args[1];
        String outdir = args[2];
        System.out.println("Checking " + basename + " in " + indir);
        SortedSet<CompilationProblem> problems = new TreeSet<CompilationProblem>();
        Layout layout = null;
        try {
            FileLoader loader = new FileLoader(indir);
            layout = loader.loadLayout(basename, problems);
            if(layout != null) {
                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.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);
            }
        }
    }
}
