package syntaxtreegenerator;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.util.HashMap;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;

public class TestNewFeatures {
    private static HashMap<String, File[]> javFiles = new HashMap<>();

    @BeforeAll
    public static void setUp() {
        final String testFileDirectory = "resources/syntaxtreegenerator/javFiles/";
        final String expectedASTDirectory = "resources/syntaxtreegenerator/";
        File dir = new File(testFileDirectory);
        for (File f : dir.listFiles(new JavFilter())) {
            String basefilename = f.getName().replace(".jav", "");
            // javFiles.put(basefilename, new File[] { f, new File(expectedASTDirectory + basefilename + ".ast") });
            javFiles.put(basefilename, new File[] { f, new File(expectedASTDirectory + basefilename + ".ast") });
        }
    }

    @Test
    public void instanceOfTest() {
        try {
            FileInputStream fileIn = new FileInputStream(javFiles.get("Instanceof")[1]);
            String expectedAST = new String(fileIn.readAllBytes());
            fileIn.close();
            expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
            File srcfile = javFiles.get("Instanceof")[0];
            JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
            String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
            resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
            System.out.println("Expected:\n" + new String(expectedAST));
            System.out.println("Result:\n" + new String(resultingAST));
            assertEquals("Comparing expected and resulting AST for Instanceof.jav", expectedAST, resultingAST);
        } catch (Exception exc) {
            exc.printStackTrace();
            fail("An error occured while generating the AST for Instanceof.jav");
        }
    }

    @Test
    public void recordTest() {
        try {
            FileInputStream fileIn = new FileInputStream(javFiles.get("Record")[1]);
            String expectedAST = new String(fileIn.readAllBytes());
            fileIn.close();
            expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
            File srcfile = javFiles.get("Record")[0];
            JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
            String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
            resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
            System.out.println("Expected:\n" + new String(expectedAST));
            System.out.println("Result:\n" + new String(resultingAST));
            assertEquals("Comparing expected and resulting AST for RecordTest.jav", expectedAST, resultingAST);
        } catch (Exception exc) {
            exc.printStackTrace();
            fail("An error occured while generating the AST for RecordTest.jav");
        }
    }

    @Test
    public void sealedTest() {
        try {
            FileInputStream fileIn = new FileInputStream(javFiles.get("Sealed")[1]);
            String expectedAST = new String(fileIn.readAllBytes());
            fileIn.close();
            expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
            File srcfile = javFiles.get("Sealed")[0];
            JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
            String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
            resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
            System.out.println("Expected:\n" + new String(expectedAST));
            System.out.println("Result:\n" + new String(resultingAST));
            assertEquals("Comparing expected and resulting AST for Sealed.jav", expectedAST, resultingAST);
        } catch (Exception exc) {
            exc.printStackTrace();
            fail("An error occured while generating the AST for Sealed.jav");
        }
    }

    @Test
    public void switchTest() {
        try {
            FileInputStream fileIn = new FileInputStream(javFiles.get("Switch")[1]);
            String expectedAST = new String(fileIn.readAllBytes());
            fileIn.close();
            expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
            File srcfile = javFiles.get("Switch")[0];
            JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
            String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
            resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
            System.out.println("Expected:\n" + new String(expectedAST));
            System.out.println("Result:\n" + new String(resultingAST));
            assertEquals("Comparing expected and resulting AST for Switch.jav", expectedAST, resultingAST);
        } catch (Exception exc) {
            exc.printStackTrace();
            fail("An error occured while generating the AST for Switch.jav");
        }
    }

    @Test
    public void patternMatching() {
        try {
            FileInputStream fileIn = new FileInputStream(javFiles.get("PatternMatching")[1]);
            String expectedAST = new String(fileIn.readAllBytes());
            fileIn.close();
            expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
            File srcfile = javFiles.get("PatternMatching")[0];
            JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
            String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
            resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
            System.out.println("Expected:\n" + new String(expectedAST));
            System.out.println("Result:\n" + new String(resultingAST));
            assertEquals("Comparing expected and resulting AST for PatternMatching.jav", expectedAST, resultingAST);
        } catch (Exception exc) {
            exc.printStackTrace();
            fail("An error occured while generating the AST for PatternMatching.jav");
        }
    }
}