package metalexer;

import java.io.PrintWriter;

/** Generates metalexer.*{Warning/Error}Tests from the provided list file. */
public abstract class ProblemTestGenerator extends AbstractTestGenerator {
    private final String prefix;
    private final String problemType;

    protected ProblemTestGenerator(String prefix, String problemType) {
        super("/metalexer/" + prefix + problemType + "Tests.java");
        this.prefix = prefix;
        this.problemType = problemType;
    }

    protected void printHeader(PrintWriter testFileWriter) {
        testFileWriter.println("package metalexer;");
        testFileWriter.println();
        testFileWriter.println("import java.util.List;");
        testFileWriter.println("import java.util.SortedSet;");
        testFileWriter.println("import java.util.TreeSet;");
        testFileWriter.println();
        testFileWriter.println("import metalexer.ast." + prefix + ";");
        testFileWriter.println();
        testFileWriter.println("public class " + prefix + problemType + "Tests extends " + prefix + "ParserFailTestBase {");
        //NB: not a typo - do extend ParserFailTestBase
    }

    protected void printMethod(PrintWriter testFileWriter, String testName) {
        String methodName = "test_" + testName;
        String outFileName = "test/frontend/" + testName + ".out";
        testFileWriter.println();
        testFileWriter.println("    public void " + methodName + "() throws Exception {");
        testFileWriter.println("        FileLoader loader = new FileLoader(\"test/frontend\");");
        testFileWriter.println("        SortedSet<CompilationProblem> actualProblems = new TreeSet<CompilationProblem>();");
        testFileWriter.println("        " + prefix + " node = loader.load" + prefix + "(\"" + testName + "\", actualProblems);");
        testFileWriter.println("        assertTrue(node.subtreeNodesHaveCorrectParents());");
        testFileWriter.println("        node = node.processInheritance(loader, actualProblems);");
        testFileWriter.println("        assertTrue(node.subtreeNodesHaveCorrectParents());");
        testFileWriter.println("        List<String> expectedErrors = readErrors(\"" + outFileName + "\");");
        testFileWriter.println("        assertEquals(expectedErrors, ProblemUtil.extract" + problemType + "s(actualProblems));");
        testFileWriter.println("    }");
    }

    protected void printFooter(PrintWriter testFileWriter) {
        testFileWriter.println("}");
        testFileWriter.println();
    }
}
