package bytecode;

import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import org.junit.Test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
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.HashMap;
import java.util.List;

import static org.junit.Assert.*;

public class JavaTXCompilerTest  {

    private static final String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
    private static final List<File> filesToTest = new ArrayList<>();
    
    protected String fileName = "";
    
    @Test
    public void test() throws IOException, java.lang.ClassNotFoundException {
    		System.out.println(rootDirectory);
        filesToTest.add(new File(rootDirectory+fileName+".jav"));
        System.out.println(rootDirectory+fileName+".jav");
        JavaTXCompiler compiler = new JavaTXCompiler(filesToTest);
        for(File f : filesToTest){
            String content = readFile(f.getPath(), StandardCharsets.UTF_8);
            List<ResultSet> typeinferenceResult = compiler.typeInference();
            HashMap<String,byte[]> bytecode = this.getBytecode(compiler.sourceFiles.get(f), typeinferenceResult.get(0));
            
//            for(ResultPair ep : typeinferenceResult.get(0).results) {
//            		System.out.println(ep.getLeft() + " ->" + ep.getRight());
//            }
            
            String name;
            int pos = f.getName().lastIndexOf(".");
            if(pos != -1) {
               name = f.getName().substring(0, pos);
            }
            this.writeClassFile(bytecode);
        }

    }
    

    public HashMap<String,byte[]> getBytecode(SourceFile sf, ResultSet resultSet) {
    		HashMap<String,byte[]> classFiles = new HashMap<>();
    		BytecodeGen bytecodeGen = new BytecodeGen(classFiles,resultSet);
    		bytecodeGen.visit(sf);
    		return bytecodeGen.getClassFiles();
	}
    
    public void writeClassFile(HashMap<String,byte[]> classFiles) {
    		FileOutputStream output;
    		for(String name : classFiles.keySet()) {
    			byte[] bytecode = classFiles.get(name);
    			try {
    				System.out.println("generating "+name+ ".class file ...");
    				output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
    				output.write(bytecode);
    				output.close();
    				System.out.println(name+".class file generated");
    			} catch (FileNotFoundException e) {
    				e.printStackTrace();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		
    }

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

}