package TP2;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;

import java.nio.file.Files;
import java.nio.file.Paths;

import org.antlr.runtime.ANTLRFileStream;
import org.antlr.runtime.ANTLRInputStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;

import TP2.asd.Program.*;
import TP2.llvm.ProgramLLVM;
import TP2.llvm.ProgramLLVM.*;

import java.util.*;


/*

./gradlew build

java -jar build/libs/TP2.jar tests/fragment0/priority2.vsl

java -jar build/libs/TP2.jar tests/aLaMain.vsl

(/!\ pas besoin, le main le fait tout seul /!\) java -jar build/libs/TP2.jar tests/fragment1/while2.vsl > tests/fragment1/while2.ll

clang tests/aLaMain.ll -o tests/aLaMain

*/

public class Main {
  static Boolean TESTAUTOMOD = false;
  public static void main(String[] args) {
    try {
      // Set input
      CharStream input;
      if (args.length == 0) {
        // From standard input
        input = new ANTLRInputStream(System.in);
      } else {
        // From file name in first argument
        input = new ANTLRFileStream(args[0]);
      }

      // Instantiate Lexer
      VSLLexer lexer = new VSLLexer(input);
      CommonTokenStream tokens = new CommonTokenStream(lexer);

      // Instantiate Parser
      VSLParser parser = new VSLParser(tokens);

      // Parse
      ProgramImp ast = parser.program();

      // Pretty-print the program (to debug parsing)

      if(!TESTAUTOMOD) System.out.println("\nVSL:\n");
      
      if(!TESTAUTOMOD) System.out.println(ast.prettyprinter());

      // Verify the program semantic

      // Generate the intermediate representation
      if(!TESTAUTOMOD) System.out.println("\nLLVM:\n");

      ProgramLLVMImp astLLVM = ast.toLLVM();

      String llvmStr = astLLVM.prettyprinter();
      System.out.println(llvmStr);
      
      /*
      utiliser la commande :
      java -jar build/libs/TP2.jar file.vsl > file.ll
      provoque peut provoquer de mauvais encodage (UTF16(LE) au lieu d'UTF8)
      et empêche l'utilisation de print pour autre chose
      */
      if(!TESTAUTOMOD){
        String sortieLLVM = args[0].replace(".vsl", ".ll");
        Files.write(
                  Paths.get(sortieLLVM),
                  llvmStr.getBytes(StandardCharsets.UTF_8)
              );
              
        System.out.println("\n[VSL compile succes] : " + args[0] + " -> " + sortieLLVM);
        System.out.println("Pour compiler en bin utilisez :");
        System.out.println("clang " + sortieLLVM + " -o " + sortieLLVM.replace(".ll", "") + "\n");
      }

    } catch (IOException | RecognitionException e) {
      e.printStackTrace();
      throw new RuntimeException("Unable to proceed");
    }
  }
}
