import { generateAutoGeneratedWarningText, generateAutoGeneratedWarningFrame } from "@/utils/auto-generated";

describe("generateAutoGeneratedWarningText", () => {
    test("generates the correct warning text without a source file name", () => {
        const warning = generateAutoGeneratedWarningText();

        expect(warning).toMatch("WARNING: AUTO-GENERATED FILE - DO NOT EDIT!");
        expect(warning).not.toMatch("To make changes to the contents of this file, please modify");
    });

    test("generates the correct warning text with a source file name", () => {
        const warning = generateAutoGeneratedWarningText("test.ts");

        expect(warning).toMatch("WARNING: AUTO-GENERATED FILE - DO NOT EDIT!");
        expect(warning).toMatch("To make changes to the contents of this file, please modify the test.ts file instead.");
    });
});

describe("generateAutoGeneratedWarningFrame", () => {
    test("generates a warning frame with default options", () => {
        const frame = generateAutoGeneratedWarningFrame();

        expect(frame).toMatch(/^#\s+WARNING: AUTO-GENERATED FILE - DO NOT EDIT!\s+#$/m);
        expect(frame).toMatch(/^#\s+Please be advised that this is an auto-generated file and should NOT be modified. Any changes made to this file WILL BE OVERWRITTEN.\s+#$/m);
    });

    test("generates a warning frame with a custom message", () => {
        const frame = generateAutoGeneratedWarningFrame({ message: "Custom message" });

        expect(frame).toMatch(/^#\sCustom message\s#$/m);
    });

    test("generates a warning frame with custom frame style", () => {
        const frame = generateAutoGeneratedWarningFrame({
            style: {
                lineStart: "/** ",
                filler: "=",
                lineEnd: " **/",
            },
        });
        expect(frame).toMatch(/^\/\*\*\s=+\s\*\*\/$/m);
        expect(frame).toMatch(/^\/\*\*\s+WARNING: AUTO-GENERATED FILE - DO NOT EDIT!\s+\*\*\/$/m);
        expect(frame).toMatch(/^\/\*\*\s+Please be advised that this is an auto-generated file and should NOT be modified. Any changes made to this file WILL BE OVERWRITTEN.\s+\*\*\/$/m);
    });

    test("generates a warning frame respecting the lineWidth option", () => {
        const frame = generateAutoGeneratedWarningFrame({ lineWidth: 40 });
        const lines = frame.split(/\r?\n/);
        const lineWidths = new Set(lines.map(x => x.length));
        const lineWidth = [...lineWidths.values()][0];

        expect(lineWidths.size).toBe(1);
        expect(Math.abs(40 - lineWidth)).toBeLessThanOrEqual(1);
    });

    test("aligns message to the left when align option is 'left'", () => {
        const frame = generateAutoGeneratedWarningFrame({ align: "left" });

        expect(frame).toMatch(/^#\sWARNING: AUTO-GENERATED FILE - DO NOT EDIT!\s{2,}#$/m);
    });

    test("aligns message to the center when align option is 'center'", () => {
        const frame = generateAutoGeneratedWarningFrame({ align: "center" });

        expect(frame).toMatch(/^#\s{2,}WARNING: AUTO-GENERATED FILE - DO NOT EDIT!\s{2,}#$/m);
    });

    test("aligns message to the right when align option is 'right'", () => {
        const frame = generateAutoGeneratedWarningFrame({ align: "right" });

        expect(frame).toMatch(/^#\s{2,}WARNING: AUTO-GENERATED FILE - DO NOT EDIT!\s#$/m);
    });

    test("uses \\n as newline sequence when newline option is '\\n'", () => {
        const frame = generateAutoGeneratedWarningFrame({ newline: "\n" });

        expect(frame).toMatch(/\n/);
        expect(frame).not.toMatch(/\r\n/);
    });

    test("uses \\r\\n as newline sequence when newline option is '\\r\\n'", () => {
        const frame = generateAutoGeneratedWarningFrame({ newline: "\r\n" });

        expect(frame).toMatch(/\r\n/);
        expect(frame).not.toMatch(/[^\r]\n/);
    });

    test("uses custom string as newline sequence when newline option is a custom string", () => {
        const frame = generateAutoGeneratedWarningFrame({ newline: "NEWLINE" });

        expect(frame).toMatch(/NEWLINE/);
        expect(frame).not.toMatch(/\n/);
        expect(frame).not.toMatch(/\r\n/);
    });
});