import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { buildRuntimeTokenKey, clearScopedRuntimeAccessToken, getRuntimeAccessToken, getScopedRuntimeAccessToken, normalizeSchedulerBaseUrl, saveScopedRuntimeAccessToken, } from "./runtime-binding.js";
const originalEnv = { ...process.env };
const tempRoots = [];
function useRuntimeHome() {
    const runtimeHome = mkdtempSync(path.join(os.tmpdir(), "aws-runtime-binding-"));
    tempRoots.push(runtimeHome);
    mkdirSync(runtimeHome, { recursive: true });
    process.env.AWS_RUNTIME_HOME_DIR = runtimeHome;
    process.env.HOME = runtimeHome;
    process.env.USERPROFILE = runtimeHome;
    return runtimeHome;
}
afterEach(() => {
    process.env = { ...originalEnv };
    for (const root of tempRoots.splice(0)) {
        rmSync(root, { recursive: true, force: true });
    }
});
describe('runtime binding scheduler URL normalization', () => {
    it('repairs duplicated scheduler ports', () => {
        expect(normalizeSchedulerBaseUrl('http://127.0.0.1:8080:8080')).toBe('http://127.0.0.1:8080');
    });
    it('normalizes websocket agent URLs to scheduler HTTP origins', () => {
        expect(normalizeSchedulerBaseUrl('ws://127.0.0.1:8080/ws/agent')).toBe('http://127.0.0.1:8080');
        expect(normalizeSchedulerBaseUrl('wss://example.com/ws/agent')).toBe('https://example.com');
    });
    it("returns paired binding token only when requested scheduler URL matches", async () => {
        useRuntimeHome();
        const { saveRuntimeBinding } = await import("./runtime-binding.js");
        saveRuntimeBinding({
            accessToken: "paired-runtime-token-123456",
            instanceId: "bridge-1",
            userId: "user-a",
            schedulerBaseUrl: "http://scheduler.local:7380",
        });
        expect(getRuntimeAccessToken(undefined, "http://scheduler.local:7380/api")).toBe("paired-runtime-token-123456");
        expect(getRuntimeAccessToken(undefined, "http://scheduler.local:8080")).toBeUndefined();
    });
    it("scopes runtime tokens by user and full scheduler origin", () => {
        useRuntimeHome();
        const key7380 = saveScopedRuntimeAccessToken({
            userId: "user-a",
            serverBaseUrl: "http://scheduler.local:7380",
            accessToken: "runtime-token-7380-123456",
        });
        const key8080 = saveScopedRuntimeAccessToken({
            userId: "user-a",
            serverBaseUrl: "http://scheduler.local:8080",
            accessToken: "runtime-token-8080-123456",
        });
        expect(key7380).not.toBe(key8080);
        expect(buildRuntimeTokenKey("user-a", "http://scheduler.local:7380/api")).toBe(key7380);
        expect(getScopedRuntimeAccessToken("user-a", "http://scheduler.local:7380")).toBe("runtime-token-7380-123456");
        expect(getScopedRuntimeAccessToken("user-a", "http://scheduler.local:8080")).toBe("runtime-token-8080-123456");
        expect(clearScopedRuntimeAccessToken("user-a", "http://scheduler.local:7380")).toBe(true);
        expect(getScopedRuntimeAccessToken("user-a", "http://scheduler.local:7380")).toBeUndefined();
        expect(getScopedRuntimeAccessToken("user-a", "http://scheduler.local:8080")).toBe("runtime-token-8080-123456");
    });
});
