import { Pos } from "./token.ts";

export type Report = {
    type: "error" | "warning" | "note";
    reporter: string;
    pos?: Pos;
    msg: string;
};

export class Reporter {
    private reports: Report[] = [];
    private errorSet = false;

    public constructor(private filePath: string) {}

    public setFilePath(filePath: string) {
        this.filePath = filePath;
    }

    public reportError(report: Omit<Report, "type">) {
        this.reports.push({ ...report, type: "error" });
        this.printReport({ ...report, type: "error" });
        this.errorSet = true;
    }

    public reportWarning(report: Omit<Report, "type">) {
        this.reports.push({ ...report, type: "warning" });
        this.printReport({ ...report, type: "warning" });
    }

    private printReport({ reporter, type, pos, msg }: Report) {
        console.error(
            `${reporter} ${type}: ${msg}${
                pos ? `\n    at ${this.filePath}:${pos.line}:${pos.col}` : ""
            }`,
        );
    }

    public addNote(report: Omit<Report, "type">) {
        this.reports.push({ ...report, type: "note" });
        this.printReport({ ...report, type: "note" });
    }

    public errorOccured(): boolean {
        return this.errorSet;
    }
}

export function printStackTrace() {
    class ReportNotAnError extends Error {
        constructor() {
            super("ReportNotAnError");
        }
    }
    try {
        //throw new ReportNotAnError();
    } catch (error) {
        if (!(error instanceof ReportNotAnError)) {
            throw error;
        }
        console.log(
            error.stack?.replace("Error: ReportNotAnError", "Stack trace:") ??
                error,
        );
    }
}