import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
import { mkdtemp, rm, readFile, writeFile, stat, mkdir } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
describe("machine-key", () => {
    let tempDir;
    let configDir;
    beforeEach(async () => {
        tempDir = await mkdtemp(join(tmpdir(), "pocketcoder-machinekey-test-"));
        configDir = join(tempDir, "config", "pocketcoder");
    });
    afterEach(async () => {
        vi.restoreAllMocks();
        await rm(tempDir, { recursive: true, force: true });
    });
    async function importModule() {
        vi.resetModules();
        vi.doMock("../paths.js", () => ({
            getConfigDir: () => configDir,
        }));
        return await import("../machine-key.js");
    }
    it("should generate key on first run", async () => {
        const { getMachineKey } = await importModule();
        const key = await getMachineKey();
        expect(key).toBeDefined();
        expect(typeof key).toBe("string");
        expect(key.length).toBeGreaterThanOrEqual(64);
    });
    it("should generate a valid hex string", async () => {
        const { getMachineKey, isValidMachineKey } = await importModule();
        const key = await getMachineKey();
        expect(key).toMatch(/^[0-9a-f]{64,}$/);
        expect(isValidMachineKey(key)).toBe(true);
    });
    it("should return same key on subsequent runs", async () => {
        const { getMachineKey } = await importModule();
        const key1 = await getMachineKey();
        const key2 = await getMachineKey();
        expect(key1).toBe(key2);
    });
    it("should persist key to config directory", async () => {
        const { getMachineKey } = await importModule();
        const key = await getMachineKey();
        const stored = await readFile(join(configDir, "machine-key"), "utf-8");
        expect(stored.trim()).toBe(key);
    });
    it("should create config directory if it does not exist", async () => {
        const { getMachineKey } = await importModule();
        await getMachineKey();
        const dirStat = await stat(configDir);
        expect(dirStat.isDirectory()).toBe(true);
    });
    it("should set 0600 permissions on key file on Unix", async () => {
        if (process.platform === "win32")
            return;
        const { getMachineKey } = await importModule();
        await getMachineKey();
        const fileStat = await stat(join(configDir, "machine-key"));
        const mode = fileStat.mode & 0o777;
        expect(mode).toBe(0o600);
    });
    it("should regenerate key if file contains invalid content", async () => {
        await mkdir(configDir, { recursive: true });
        await writeFile(join(configDir, "machine-key"), "not-a-valid-hex-key\n");
        const { getMachineKey, isValidMachineKey } = await importModule();
        const key = await getMachineKey();
        expect(isValidMachineKey(key)).toBe(true);
    });
    it("should regenerate key if file is empty", async () => {
        await mkdir(configDir, { recursive: true });
        await writeFile(join(configDir, "machine-key"), "");
        const { getMachineKey, isValidMachineKey } = await importModule();
        const key = await getMachineKey();
        expect(isValidMachineKey(key)).toBe(true);
    });
    describe("deleteMachineKey", () => {
        it("should delete the machine key file", async () => {
            const { getMachineKey, deleteMachineKey } = await importModule();
            // Generate a key first
            await getMachineKey();
            // Verify file exists
            const keyPath = join(configDir, "machine-key");
            const before = await stat(keyPath).catch(() => null);
            expect(before).not.toBeNull();
            // Delete it
            await deleteMachineKey();
            // Verify file is gone
            const after = await stat(keyPath).catch(() => null);
            expect(after).toBeNull();
        });
        it("should not throw if key file does not exist", async () => {
            const { deleteMachineKey } = await importModule();
            // Should not throw
            await expect(deleteMachineKey()).resolves.toBeUndefined();
        });
    });
    describe("isValidMachineKey", () => {
        it("should accept valid 64-char hex string", async () => {
            const { isValidMachineKey } = await importModule();
            const validKey = "a".repeat(64);
            expect(isValidMachineKey(validKey)).toBe(true);
        });
        it("should accept longer hex strings", async () => {
            const { isValidMachineKey } = await importModule();
            const longKey = "abcdef0123456789".repeat(8);
            expect(isValidMachineKey(longKey)).toBe(true);
        });
        it("should reject short strings", async () => {
            const { isValidMachineKey } = await importModule();
            expect(isValidMachineKey("abc123")).toBe(false);
        });
        it("should reject non-hex characters", async () => {
            const { isValidMachineKey } = await importModule();
            expect(isValidMachineKey("g".repeat(64))).toBe(false);
        });
        it("should reject empty string", async () => {
            const { isValidMachineKey } = await importModule();
            expect(isValidMachineKey("")).toBe(false);
        });
    });
});
//# sourceMappingURL=machine-key.test.js.map