import { describe, expect, test } from "vitest";
import { getDefaultLocalSettings } from "../src/settings/Settings";
import { normalizeLocalTocSettings, parseLocalTocSettingsYaml } from "../src/settings/localTocSettings";
import type { LocalTocSettings } from "../src/types";

describe("local toc settings parsing", () => {
    test("sanitizes compact yaml before parsing nested settings", () => {
        // Arrange
        const yaml = [ "title:", "  name:Local TOC", "  level:2", "levels:", "  min:2 max:6" ].join("\n");

        // Act
        const result = parseLocalTocSettingsYaml(yaml);

        // Assert
        expect(result.errors).toEqual([]);
        expect(result.settings.title.name).toBe("Local TOC");
        expect(result.settings.title.level).toBe(2);
        expect(result.settings.levels).toEqual({ min: 2, max: 6 });
    });

    test("coerces scalar title, exclude, and omit values into strings", () => {
        // Arrange
        const yaml = [ "title:", "  name: 42", "exclude: 123", "omit:", "  - 1", "  - true" ].join("\n");

        // Act
        const result = parseLocalTocSettingsYaml(yaml);

        // Assert
        expect(result.errors).toEqual([]);
        expect(result.settings.title.name).toBe("42");
        expect(result.settings.exclude).toBe("123");
        expect(result.settings.omit).toEqual([ "1", "true" ]);
    });

    test("returns defaults and validation errors for invalid heading ranges", () => {
        // Arrange
        const yaml = [ "title:", "  level: 7", "levels:", "  min: 6", "  max: 1" ].join("\n");

        // Act
        const result = parseLocalTocSettingsYaml(yaml);

        // Assert
        expect(result.settings).toEqual(getDefaultLocalSettings());
        expect(result.errors).toEqual([
            "'title.level' must be an integer between 1 and 6.",
            "'levels.min' cannot be greater than 'levels.max'."
        ]);
    });

    test("normalizes missing branches and clones omit arrays", () => {
        // Arrange
        const omit = [ "Heading 1" ];
        const source: Partial<LocalTocSettings> = {
            title: { name: "TOC", level: 2, center: true },
            omit,
            levels: { min: 2, max: 4 }
        };

        // Act
        const normalized = normalizeLocalTocSettings(source);
        omit.push("Heading 2");

        // Assert
        expect(normalized).toEqual({
            title: { name: "TOC", level: 2, center: true },
            exclude: null,
            omit: [ "Heading 1" ],
            levels: { min: 2, max: 4 }
        });
    });
});
