/**
 * Unit tests for handleBindingAnalysis.js
 */

import { buildHandleBindingsAtLine } from "../../core/src/analysis/handleBindingAnalysis.js";

/**
 * Minimal TextDocument stub used by the tests.
 */
function makeDocument(lines) {
    return {
        lineCount: lines.length,
        lineAt: (i) => ({ text: lines[i] })
    };
}

describe("buildHandleBindingsAtLine", () => {
    test("returns empty map when no index functions present", () => {
        const doc = makeDocument(["VAR sHandle : SHORT", "sHandle = 0"]);
        expect(buildHandleBindingsAtLine(doc, 2).size).toBe(0);
    });

    test("binds handle to table after INDEX_OPEN_STANDARD", () => {
        const doc = makeDocument([
            "VAR sHandle : SHORT",
            'sHandle = INDEX_OPEN_STANDARD("MD", 0, sHandle)'
        ]);
        const bindings = buildHandleBindingsAtLine(doc, 2);
        expect(bindings.get("shandle")).toBe("MD");
    });

    test("does not include binding when targetLine is before the open call", () => {
        const doc = makeDocument([
            "VAR sHandle : SHORT",
            'sHandle = INDEX_OPEN_STANDARD("MD", 0, sHandle)'
        ]);
        // Scanning only up to line 1 — the open call is on line 1 (index 1), so excluded
        const bindings = buildHandleBindingsAtLine(doc, 1);
        expect(bindings.has("shandle")).toBe(false);
    });

    test("binding is removed after INDEX_CLOSE", () => {
        const doc = makeDocument([
            "VAR sHandle : SHORT",
            'sHandle = INDEX_OPEN_STANDARD("MD", 0, sHandle)',
            "sHandle = INDEX_CLOSE(sHandle)"
        ]);
        const bindings = buildHandleBindingsAtLine(doc, 3);
        expect(bindings.has("shandle")).toBe(false);
    });

    test("re-opening after close re-establishes binding", () => {
        const doc = makeDocument([
            "VAR sHandle : SHORT",
            'sHandle = INDEX_OPEN_STANDARD("MD", 0, sHandle)',
            "sHandle = INDEX_CLOSE(sHandle)",
            'sHandle = INDEX_OPEN_STANDARD("D2", 0, sHandle)'
        ]);
        const bindings = buildHandleBindingsAtLine(doc, 4);
        expect(bindings.get("shandle")).toBe("D2");
    });

    test("tracks two handles independently", () => {
        const doc = makeDocument([
            "VAR sHandleA : SHORT",
            "VAR sHandleB : SHORT",
            'sHandleA = INDEX_OPEN_STANDARD("MD", 0, sHandleA)',
            'sHandleB = INDEX_OPEN_STANDARD("D2", 1, sHandleB)'
        ]);
        const bindings = buildHandleBindingsAtLine(doc, 4);
        expect(bindings.get("shandlea")).toBe("MD");
        expect(bindings.get("shandleb")).toBe("D2");
    });

    test("closing one handle does not affect the other", () => {
        const doc = makeDocument([
            "VAR sHandleA : SHORT",
            "VAR sHandleB : SHORT",
            'sHandleA = INDEX_OPEN_STANDARD("MD", 0, sHandleA)',
            'sHandleB = INDEX_OPEN_STANDARD("D2", 1, sHandleB)',
            "sHandleA = INDEX_CLOSE(sHandleA)"
        ]);
        const bindings = buildHandleBindingsAtLine(doc, 5);
        expect(bindings.has("shandlea")).toBe(false);
        expect(bindings.get("shandleb")).toBe("D2");
    });
});
