package metalexer;

public class CompilationProblem implements Comparable<CompilationProblem> {
    private final String filename;
    private final int line;
    private final int col;
    private final String message;

    public CompilationProblem(String filename, String message) {
        this.filename = filename;
        this.line = Integer.MAX_VALUE;
        this.col = Integer.MAX_VALUE;
        this.message = message;
    }

    public CompilationProblem(String filename, int line, int col, String message) {
        this.filename = filename;
        this.line = line;
        this.col = col;
        this.message = message;
    }

    public String getFilename() {
        return filename;
    }

    public int getLine() {
        return line;
    }

    public int getColumn() {
        return col;
    }

    public String getMessage() {
        return message;
    }

    public String toString() {
        if(this.line == Integer.MAX_VALUE && this.col == Integer.MAX_VALUE) {
            if(filename == null) {
                return message;
            }
            return filename + "  " + message;
        } else {
            if(filename == null) {
                //programming error
                throw new RuntimeException("Error has a position but not a filename: " + message + ".");
            }
            return filename + " [" + line + ", " + col + "]  " + message;
        }
    }

    public int compareTo(CompilationProblem o) {
        if(o == null) {
            return -1; //nulls at the end
        } else if(compare(this.filename, o.filename) != 0) {
            return compare(this.filename, o.filename);
        } else if(this.line < o.line) {
            return -1;
        } else if(this.line > o.line) {
            return 1;
        } else if(this.col < o.col) {
            return -1;
        } else if(this.col > o.col) {
            return 1;
        } else {
            return compare(this.message, o.message);
        }
    }

    public int compare(String s1, String s2) {
        if(s1 == null && s2 != null) {
            return 1;
        } else if(s1 != null && s2 == null) {
            return -1;
        } else if(s1 == null && s2 == null) {
            return 0;
        } else {
            return s1.compareTo(s2);
        }
    }
}
