import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { configureStartupConfig, ensureStartupConfig, } from "./startup-config-wizard.js";
class FakePrompt {
    constructor(answers) {
        this.answers = answers;
        this.index = 0;
        this.closed = false;
        this.prompts = [];
    }
    async question(prompt) {
        this.prompts.push(prompt);
        return this.answers[this.index++] ?? "";
    }
    close() {
        this.closed = true;
    }
}
const tempRoots = [];
function createConfigPath() {
    const root = mkdtempSync(path.join(os.tmpdir(), "aws-bridge-wizard-"));
    tempRoots.push(root);
    return path.join(root, ".aws-bridge", "config.json");
}
afterEach(() => {
    for (const root of tempRoots.splice(0)) {
        rmSync(root, { recursive: true, force: true });
    }
});
describe("startup config wizard", () => {
    it("does not prompt when config file already exists", async () => {
        const configPath = createConfigPath();
        mkdirSync(path.dirname(configPath), { recursive: true });
        writeFileSync(configPath, "{}", "utf-8");
        const prompt = new FakePrompt([]);
        const result = await ensureStartupConfig({ configPath, interactive: true, prompt });
        expect(result).toBe("exists");
        expect(prompt.closed).toBe(false);
    });
    it("writes generated connection key when user chooses no", async () => {
        const configPath = createConfigPath();
        const prompt = new FakePrompt(["n"]);
        const result = await ensureStartupConfig({
            configPath,
            interactive: true,
            prompt,
            generateConnectionKey: () => "awsb_test_generated_key",
        });
        expect(result).toBe("skipped");
        expect(JSON.parse(readFileSync(configPath, "utf-8"))).toEqual({
            connectionKey: "awsb_test_generated_key",
        });
    });
    it("writes connection key and auto register target from interactive answers", async () => {
        const configPath = createConfigPath();
        const prompt = new FakePrompt([
            "y",
            "gkmzjaznX55..",
            "http://127.0.0.1:8080",
            "至强主机",
            "aws_live_crh_g0GGrg5IntODg1sFwnas7qf4yGrcwoisDWPBtd8",
            "127.0.0.1",
        ]);
        const result = await ensureStartupConfig({ configPath, interactive: true, prompt });
        expect(result).toBe("created");
        expect(JSON.parse(readFileSync(configPath, "utf-8"))).toEqual({
            connectionKey: "gkmzjaznX55..",
            autoRegisterTargets: [
                {
                    serverUrl: "http://127.0.0.1:8080",
                    instanceName: "至强主机",
                    userKey: "aws_live_crh_g0GGrg5IntODg1sFwnas7qf4yGrcwoisDWPBtd8",
                    registerIp: "127.0.0.1",
                },
            ],
        });
    });
    it("writes generated connection key and does not block startup in non-interactive environments", async () => {
        const configPath = createConfigPath();
        const result = await ensureStartupConfig({
            configPath,
            interactive: false,
            generateConnectionKey: () => "awsb_non_interactive_key",
        });
        expect(result).toBe("non-interactive");
        expect(JSON.parse(readFileSync(configPath, "utf-8"))).toEqual({
            connectionKey: "awsb_non_interactive_key",
        });
    });
    it("supports environment opt-out for unattended startup", async () => {
        const configPath = createConfigPath();
        const result = await ensureStartupConfig({
            configPath,
            interactive: true,
            env: { AWS_BRIDGE_SKIP_SETUP: "true" },
            generateConnectionKey: () => "awsb_env_skip_key",
        });
        expect(result).toBe("skipped");
        expect(JSON.parse(readFileSync(configPath, "utf-8"))).toEqual({
            connectionKey: "awsb_env_skip_key",
        });
    });
    it("reconfigures existing config and keeps current values on empty input", async () => {
        const configPath = createConfigPath();
        mkdirSync(path.dirname(configPath), { recursive: true });
        writeFileSync(configPath, JSON.stringify({
            connectionKey: "old-connection-key",
            autoRegisterTargets: [
                {
                    serverUrl: "http://old-server:7380",
                    instanceName: "old-instance",
                    userKey: "old-user-key",
                    registerIp: "10.0.0.8",
                },
            ],
        }, null, 2), "utf-8");
        const prompt = new FakePrompt(["", "", "", "", ""]);
        const result = await configureStartupConfig({
            configPath,
            interactive: true,
            prompt,
        });
        expect(result).toBe("configured");
        expect(JSON.parse(readFileSync(configPath, "utf-8"))).toEqual({
            connectionKey: "old-connection-key",
            autoRegisterTargets: [
                {
                    serverUrl: "http://old-server:7380",
                    instanceName: "old-instance",
                    userKey: "old-user-key",
                    registerIp: "10.0.0.8",
                },
            ],
        });
        expect(prompt.prompts).toEqual([
            "connectionKey（面板连接 Bridge 的密钥）（默认使用当前值 old-connection-key，直接回车保留）: ",
            "serverUrl（调度中心地址）（默认使用当前值 http://old-server:7380，直接回车保留）: ",
            "instanceName（实例名称）（默认使用当前值 old-instance，直接回车保留）: ",
            "userKey（用户 API Key）（默认使用当前值 old-user-key，直接回车保留）: ",
            "registerIp（Bridge 对外访问 IP）（默认使用当前值 10.0.0.8，直接回车保留）: ",
        ]);
    });
    it("reconfigures existing config with changed values", async () => {
        const configPath = createConfigPath();
        mkdirSync(path.dirname(configPath), { recursive: true });
        writeFileSync(configPath, JSON.stringify({
            connectionKey: "old-connection-key",
            autoRegisterTargets: [
                {
                    serverUrl: "http://old-server:7380",
                    instanceName: "old-instance",
                    userKey: "old-user-key",
                    registerIp: "10.0.0.8",
                },
            ],
        }), "utf-8");
        const prompt = new FakePrompt([
            "new-connection-key",
            "http://new-server:7380",
            "new-instance",
            "new-user-key",
            "10.0.0.9",
        ]);
        const result = await configureStartupConfig({
            configPath,
            interactive: true,
            prompt,
        });
        expect(result).toBe("configured");
        expect(JSON.parse(readFileSync(configPath, "utf-8"))).toEqual({
            connectionKey: "new-connection-key",
            autoRegisterTargets: [
                {
                    serverUrl: "http://new-server:7380",
                    instanceName: "new-instance",
                    userKey: "new-user-key",
                    registerIp: "10.0.0.9",
                },
            ],
        });
    });
});
