package compiler;

import filehandler.JsonWriter;
import grammar.ReceiptLexer;
import grammar.ReceiptParser;
import infrastructure.exceptions.JsonExportException;
import infrastructure.exceptions.TranslationException;
import infrastructure.json.JsonStructure;
import infrastructure.translator.Translator;
import java.io.File;
import java.io.FileInputStream;
import java.util.LinkedList;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;

/**
 *
 * @author Lucas
 */
public class Compiler {

    private static LinkedList<String> filesToCompile;

    private String in;
    private String out;
    
    private static int Id;

    Compiler(String in) {
        try {
            if (in.isEmpty()) {
                throw new IllegalArgumentException("Parameter in cannot be an empty String");
            }

            this.in = in;
            
            String parent = new File(in).getParentFile().getName();
            out = in.substring(0, in.indexOf("input")) + "output\\";
            
            if (!parent.equals("input")) {
                out += parent + "\\";
            }
            
            out += (++Id) + ".json";
        } catch (NullPointerException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }
    
    Compiler(String in, String out) {
        this(in);
        this.out = out;
    }

    /**
     * @param args the command line arguments
     * @throws java.lang.Exception
     */
    public static void main(String[] args) throws Exception {
        filesToCompile = new LinkedList<>();

        if (args.length > 0) {
            File file = new File(args[0]);
            
            if (file.isDirectory()) {
                for (File child : file.listFiles()) {
                    filesToCompile.add(child.getPath());
                }
                filesToCompile.add(file.getPath());
            }
        } else {
            filesToCompile.add("src/input/test.txt");
        }
        
        for (String file : filesToCompile) {
            try {
                new Compiler(file).start();
            
            } catch (IllegalArgumentException e) {
                System.err.println("The input file name is invalid: \"" + file + "\"");
            
            } catch (RecognitionException e) {
                System.err.println("Recognition error on file \"" + file + "\": "
                + e.getMessage());

            } catch (TranslationException e) {
                System.err.println("Translation error on file \"" + file + "\": "
                    + e.getMessage());
                
            } catch (JsonExportException e) {
                System.err.println("Json exportation error on file \"" + file + "\": "
                    + e.getMessage());
            } catch (Exception e) {
                System.err.println("An error has occured while compiling file \"" + file + "\": "
                    + e.getMessage());
            }
        }
    }

    private void start() throws Exception {
        System.out.println("\nCompilation proccess has started. File being compiled: " + in);

        ANTLRInputStream inputStream = new ANTLRInputStream(new FileInputStream(in));

        ReceiptLexer lexer = new ReceiptLexer(inputStream);
        ReceiptParser parser = new ReceiptParser(new CommonTokenStream(lexer));

        // parse input file and retrieve its JsonStructure
        JsonStructure tree = parser.receipt().e;

        System.out.println("Parsing completed.");

        // print JsonStructure to the String result
        String result = new Translator(tree)
                .run()
                .export();

        // export file with printed JsonStructure
        new JsonWriter(out, result)
                .export();

        System.out.println("Finished!");
    }
}

@@ -133,29 +133,123 @@
 ure.
-exceptions.JsonExport
+SemanticListener;%0D%0Aimport infrastructure.exceptions.JsonExportException;%0D%0Aimport infrastructure.exceptions.Semantic
 Exce
@@ -2056,32 +2056,54 @@
              %7D%0D%0A
+            %7D else %7B%0D%0A
                 
@@ -2692,24 +2692,238 @@
 sage());%0D%0A%0D%0A
+            %7D catch (SemanticException e) %7B%0D%0A                System.err.println(%22Semantic error on file %5C%22%22 + file + %22%5C%22.%5Cn%22%0D%0A                        + %22The compilation of this specific file cannot continue.%22);%0D%0A%0D%0A
             
@@ -3743,16 +3743,18 @@
 r lexer 
+  
 = new Re
@@ -3914,32 +3914,32 @@
  JsonStructure%0D%0A
-
         JsonStru
@@ -3971,16 +3971,402 @@
 pt().e;%0D
+%0A        %0D%0A        SemanticListener semantics = new SemanticListener(tree);%0D%0A        %0D%0A        if(semantics.hasErrors()) %7B%0D%0A            System.err.println(%22%5CnSemantic errors were found:%22);%0D%0A            %0D%0A            for (String error : semantics.errors()) %7B%0D%0A                System.err.println(error);%0D%0A            %7D%0D%0A            %0D%0A            throw new SemanticException();%0D%0A        %7D%0D
 %0A%0D%0A     

Fix exception thrown when inputing a directory