/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package compiler;

import common.ErrorReport;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;

/**
 *
 * @author Eugenio
 */
public class SyntaxError extends BaseErrorListener implements ErrorReport {

    protected List<SyntaxErrorItem> items;

    public SyntaxError() {
        this.items = new ArrayList<SyntaxErrorItem>();
    }

    @Override
    public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
        items.add(new SyntaxErrorItem(line, charPositionInLine, msg, offendingSymbol, e));
    }

//    public boolean hasErrors() {
//        return this.items.size() > 0;
//    }
    @Override
    public String toString() {
        if (!HasError()) {
            return "0 errors";
        }
        StringBuilder builder = new StringBuilder();
        for (SyntaxErrorItem s : items) {
            builder.append(String.format("%s\n", s));
        }
        return builder.toString();
    }

    public void PrintErros() {
        System.out.println(toString());
    }

    @Override
    public boolean HasError() {
        return !items.isEmpty();
    }

    protected class SyntaxErrorItem {

        private int line;
        private Object offendingSymbol;
        private int column;
        private String msg;
        private RecognitionException oops;
        protected String file;

        SyntaxErrorItem(int line, int column, String msg, Object symbol, RecognitionException oops) {
            this.line = line;
            this.column = column;
            this.offendingSymbol = symbol;
            this.oops = oops;

            if (oops != null) {
                String path[] = oops.getInputStream().getSourceName().split("\\\\");
                file = path[path.length - 1];
//                System.out.println(oops.getClass().getCanonicalName());
            }
            if (msg.contains("extraneous input")) {
                msg = msg.replace("extraneous input", "Entrada invalida");
                msg = msg.replace("expecting", "esperando");
            } else if (msg.contains("recognition")) {
                msg = msg.replace("token recognition", "Erro de reconhecimento do simbólo");
            } else if (msg.contains("no viable")) {
                msg = msg.replace("no viable alternative at input", "Não encontrou alternativa para a entrada");
            } else if (msg.contains("missing")) {
                msg = msg.replace("missing", "Está faltando");
                msg = msg.replace("at", "antes");
            } else if (msg.contains("mismatched")) {
                msg = msg.replace("mismatched input", "Entrada incompativel");
                msg = msg.replace("expecting", "esperando");
            }
            this.msg = msg;
        }

        @Override
        public String toString() {
            String format;
            format = "[%d:%d|%s\t] SyntaxError: %s";
            if (oops == null) {
//                return String.format("[%d:%d] %s", line, column, msg);
                return String.format(format, line, column, file, msg);
//                return String.format("[%d:%d] %s", line, column, msg);
            } else {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                oops.printStackTrace(pw);
                pw.close();
//                return String.format("[%d:%d] %s\n%s", line, column, msg, sw.toString());
                return String.format(format, line, column, file, msg);
            }
        }
    }
}
