package typeinference;

import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
import de.dhbwstuttgart.typedeployment.TypeInsert;
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class JavaTXCompilerTest {

    public static final String rootDirectory = System.getProperty("user.dir")+"/test/javFiles/";

    @Test
    public void finiteClosure() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"fc.jav"));
    }
    @Test
    public void lambda() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"Lambda.jav"));
    }
    @Test
    public void lambda2() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"Lambda2.jav"));
    }
    @Test
    public void lambda3() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"Lambda3.jav"));
    }
    @Test
    public void mathStruc() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"mathStruc.jav"));
    }
    @Test
    public void generics() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"Generics.jav"));
    }
    @Test
    public void faculty() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"Faculty.jav"));
    }
    @Test
    public void facultyTyped() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"FacultyTyped.jav"));
    }
    @Test
    public void matrix() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"Matrix.jav"));
    }
    @Test
    public void vector() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"Vector.jav"));
    }
    @Test
    public void lambdaRunnable() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"LambdaRunnable.jav"));
    }
    @Test
    public void expressions() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"Expressions.jav"));
    }
    @Test
    public void addLong() throws IOException, ClassNotFoundException {
        execute(new File(rootDirectory+"AddLong.jav"));
    }

    private static class TestResultSet{

    }

    public TestResultSet execute(File fileToTest) throws IOException, ClassNotFoundException {
        //filesToTest.add(new File(rootDirectory+"fc.jav"));
        //filesToTest.add(new File(rootDirectory+"Lambda.jav"));
        //filesToTest.add(new File(rootDirectory+"Lambda2.jav"));
        //filesToTest.add(new File(rootDirectory+"Lambda3.jav"));
        //filesToTest.add(new File(rootDirectory+"Vector.jav"));
        //filesToTest.add(new File(rootDirectory+"Generics.jav"));
        //filesToTest.add(new File(rootDirectory+"MethodsEasy.jav"));
        //filesToTest.add(new File(rootDirectory+"Matrix.jav"));
        //filesToTest.add(new File(rootDirectory+"Import.jav"));
        //        //filesToTest.add(new File(rootDirectory+"Faculty.jav"));
        //        //filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
        //        //filesToTest.add(new File(rootDirectory+"test.jav"));
        JavaTXCompiler compiler = new JavaTXCompiler(fileToTest);
        for(File f : compiler.sourceFiles.keySet()){
            SourceFile sf = compiler.sourceFiles.get(f);
            System.out.println(ASTTypePrinter.print(sf));
            System.out.println(ASTPrinter.print(sf));
        }
        List<ResultSet> results = compiler.typeInference();

        for(File f : compiler.sourceFiles.keySet()){
            SourceFile sf = compiler.sourceFiles.get(f);
            System.out.println(ASTTypePrinter.print(sf));
            System.out.println(ASTPrinter.print(sf));
            //List<ResultSet> results = compiler.typeInference(); PL 2017-10-03 vor die For-Schleife gezogen
            assert results.size()>0;
            Set<String> insertedTypes = new HashSet<>();
            for(ResultSet resultSet : results){
                Set<TypeInsert> result = TypeInsertFactory.createTypeInsertPoints(sf, resultSet);
                assert result.size()>0;
                String content = readFile(f.getPath(), StandardCharsets.UTF_8);
                for(TypeInsert tip : result){
                    insertedTypes.add(tip.insert(content));
                }
            }
            for(String s : insertedTypes){
                System.out.println(s);
            }
        }
        return new TestResultSet();
    }

    static String readFile(String path, Charset encoding)
            throws IOException
    {
        byte[] encoded = Files.readAllBytes(Paths.get(path));
        return new String(encoded, encoding);
    }

}