package plugindevelopment;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import de.dhbwstuttgart.typeinference.Menge;

import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
import junit.framework.TestCase;


public class TypeInsertTester{

	//private static Logger inferencelog = Logger.getLogger(TypeInsertTester.class.getName());
	private static LoggerConfiguration logConfig = new LoggerConfiguration();
	static{
		{
			logConfig.setOutput(Section.TYPEINFERENCE, System.out);
			/*
	        // Ausgabeoptionen fuer die Logger
	        ConsoleAppender logAppender = new ConsoleAppender(new SimpleLayout());
	        logAppender.setTarget("System.out");
	        logAppender.activateOptions();
	        inferencelog.addAppender(logAppender); //Bei den Tests wird der Log auch in System.out geschrieben.
			*/
		}
	}
	static final String rootDirectory = System.getProperty("user.dir")+"/test/plugindevelopment/";
	
	public static void test(String sourceFileToInfere, String solutionFile){
		String inferedSource = "";
		MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
		try {
			compiler.parse(new File(rootDirectory + sourceFileToInfere));
			Menge<TypeinferenceResultSet> results = compiler.typeReconstruction();
			TestCase.assertTrue("Es darf nicht mehr als eine Lösungsmöglichkeit geben und nicht "+results.size(), results.size()==1);
			for(TypeinferenceResultSet result : results){
				TypeInsertSet point = result.getTypeInsertionPoints();
				//TestCase.assertTrue("Es muss mindestens ein TypeInsertSet vorhanden sein", points.size()>0);
				if(point.points.size()>0){
					inferedSource = point.insertAllTypes(getFileContent(rootDirectory + sourceFileToInfere));
					String solutionSource = getFileContent(rootDirectory + solutionFile);
					System.out.println("\nInferierter Source:\n"+inferedSource);
					TestCase.assertTrue("Nicht das erwartete Ergebnis", inferedSource.equals(solutionSource));
				}
			}
			
		} catch (IOException | yyException e) {
			e.printStackTrace();
			TestCase.fail();
		}
	}
	
	//Source: https://stackoverflow.com/questions/326390/how-to-create-a-java-string-from-the-contents-of-a-file
	//PS: benötigt Java 7
	public static String getFileContent(String path)throws IOException 
	{
		byte[] encoded = Files.readAllBytes(Paths.get(path));
		return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(encoded)).toString();
	}

}