package bytecode;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import org.apache.commons.bcel6.classfile.JavaClass;

import com.google.common.io.Files;

import junit.framework.TestCase;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.logger.Timewatch;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;

public class SingleClassTester {
	
	public static void compileToBytecode(String inputFile, String outputDirectory){
		LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out);
		MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
		try {
			SourceFile sf = compiler.parse(new File(inputFile));
			
			Menge<SourceFile> sourceFiles = new Menge<>();
			sourceFiles.add(sf);
			
			TypeinferenceResults results =  new TypeinferenceResults(compiler.typeReconstruction(sourceFiles));
			
			Menge<ByteCodeResult> bytecode = compiler.generateBytecode(sourceFiles, results);
			//System.out.println(bytecode);
			
			
			
			ByteCodeResult result = bytecode.firstElement();
			
			JavaClass javaClass = result.getByteCode().getJavaClass();
			javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class"));
			
			for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){
				JavaClass jc = cg.getJavaClass();
				jc.dump(new File(outputDirectory+jc.getClassName()+".class"));
			}
			
			Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN);
			
			
			
		} catch (IOException | yyException e) {
			Logger.getLogger("SingleClassTester").error(e.toString(), Section.CODEGEN);
			e.printStackTrace();
			TestCase.fail();
		}finally{
			writeLog(inputFile+".log");
		}
	}
	
	private static void writeLog(String toFile){
		String log = Logger.getWholeLog()+"\n";
		log+=Timewatch.getTimewatch().dumpTimeData();
		try {
			Files.write(log.getBytes(),new File(toFile));
		} catch (IOException e) {
			e.printStackTrace();
			TestCase.fail();
		}
	}
}