package strucType;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.strucTypes.Construct;
import de.dhbwstuttgart.strucTypes.InferredTypes;
import de.dhbwstuttgart.strucTypes.StrucTYPE;
import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet;
import de.dhbwstuttgart.strucTypes.constraint.SubTypeConstraint;
import de.dhbwstuttgart.strucTypes.exception.ImpossibleSubTypeException;
import de.dhbwstuttgart.strucTypes.printutils.PrintConstraints;
import de.dhbwstuttgart.strucTypes.printutils.PrintInferredTypes;
import de.dhbwstuttgart.strucTypes.printutils.SyntaxTreePrinter;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.SourceFile;

public class TestConstruct {
	public static final String rootDirectory = System.getProperty("user.dir") + "/test/strucType/javFiles/";
	public final PrintConstraints printConstraints = new PrintConstraints();

	@org.junit.Test
	public void test() throws ClassNotFoundException, IOException, ImpossibleSubTypeException {
		ArrayList<File> files = new ArrayList<>();
		files.add(new File(rootDirectory + "testLocalVar.jav"));
		files.add(new File(rootDirectory + "testCast.jav"));
		files.add(new File(rootDirectory + "testNew.jav"));
		files.add(new File(rootDirectory + "testFieldVar.jav"));
		files.add(new File(rootDirectory + "testFieldMethod.jav"));
		files.add(new File(rootDirectory + "testMethod.jav"));
		files.add(new File(rootDirectory + "testPaperExample.jav"));
		JavaTXCompiler compiler = new JavaTXCompiler(files);
		for (File f : compiler.sourceFiles.keySet()) {
			String name = f.getName();
			System.out.println("Filename: " + name);
			SourceFile sourceFile = compiler.sourceFiles.get(f);
			//Print SourceFile Infos
			sourceFile.accept(new SyntaxTreePrinter());
			
			StrucTYPE strucTYPE = new StrucTYPE(sourceFile);
			
			ConstraintsSet constraints = strucTYPE.getConstraints();
			printConstraints.print(constraints);
			
			InferredTypes inferredTypes = strucTYPE.getInferredTypes();
			PrintInferredTypes.print(inferredTypes);
			
			Construct construct = new Construct(constraints, inferredTypes);
			
			List<ClassOrInterface> constructedInterfaces = construct.getConstructedInterfaces();
			System.out.println("\nConstructed Interfaces:");
			constructedInterfaces.forEach(i-> i.accept(new SyntaxTreePrinter()));
			
			List<SubTypeConstraint> subTypeConstraints = construct.getSubTypeConstraints();
			printConstraints.printSubTypeConstraints(subTypeConstraints);
			
			inferredTypes = construct.getInferredTypes();
			PrintInferredTypes.print(inferredTypes);
			
			System.out.println("____________________________________________________________________________");
		}
	}
}