/**
 * Tests for register-skillset command
 * Tests that the command creates nori.json for existing skillsets that don't have one
 */
import * as fs from "fs/promises";
import * as os from "os";
import * as path from "path";
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { registerSkillsetMain } from "./registerSkillset.js";
// Mock os.homedir so getNoriSkillsetsDir() resolves to the test directory
vi.mock("os", async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        homedir: vi.fn().mockReturnValue(actual.homedir()),
    };
});
// Mock @clack/prompts for output
const mockLogError = vi.fn();
const mockNote = vi.fn();
const mockOutro = vi.fn();
vi.mock("@clack/prompts", () => ({
    log: {
        error: (msg) => mockLogError(msg),
    },
    note: (content, title) => mockNote(content, title),
    outro: (msg) => mockOutro(msg),
}));
// Mock process.exit
const mockExit = vi
    .spyOn(process, "exit")
    .mockImplementation(() => undefined);
// Mock registerSkillsetFlow
const mockRegisterSkillsetFlow = vi.fn();
vi.mock("@/cli/prompts/flows/registerSkillset.js", () => ({
    registerSkillsetFlow: () => mockRegisterSkillsetFlow(),
}));
// Mock config loading
const mockLoadConfig = vi.fn();
const mockGetActiveSkillset = vi.fn();
vi.mock("@/cli/config.js", () => ({
    loadConfig: (args) => mockLoadConfig(args),
    getActiveSkillset: (args) => mockGetActiveSkillset(args),
}));
describe("registerSkillsetMain", () => {
    let testHomeDir;
    let skillsetsDir;
    beforeEach(async () => {
        testHomeDir = await fs.mkdtemp(path.join(os.tmpdir(), "register-skillset-test-"));
        vi.mocked(os.homedir).mockReturnValue(testHomeDir);
        skillsetsDir = path.join(testHomeDir, ".nori", "profiles");
        await fs.mkdir(skillsetsDir, { recursive: true });
        mockLogError.mockClear();
        mockNote.mockClear();
        mockOutro.mockClear();
        mockExit.mockClear();
        mockRegisterSkillsetFlow.mockClear();
        mockLoadConfig.mockClear();
        mockGetActiveSkillset.mockClear();
    });
    afterEach(async () => {
        if (testHomeDir) {
            await fs.rm(testHomeDir, { recursive: true, force: true });
        }
    });
    it("should create nori.json for existing skillset without one", async () => {
        // Create existing skillset directory without nori.json
        const existingDir = path.join(skillsetsDir, "my-existing-skillset");
        await fs.mkdir(existingDir, { recursive: true });
        mockRegisterSkillsetFlow.mockResolvedValueOnce({
            description: "My existing skillset",
            license: "MIT",
            keywords: ["testing"],
            version: "1.5.0",
            repository: "https://github.com/user/repo",
        });
        const result = await registerSkillsetMain({
            skillsetName: "my-existing-skillset",
        });
        // Verify nori.json was created
        const noriJson = JSON.parse(await fs.readFile(path.join(existingDir, "nori.json"), "utf-8"));
        expect(noriJson).toEqual({
            name: "my-existing-skillset",
            version: "1.5.0",
            type: "skillset",
            description: "My existing skillset",
            license: "MIT",
            keywords: ["testing"],
            repository: "https://github.com/user/repo",
        });
        // Verify return status contains skillset name
        expect(result.success).toBe(true);
        expect(result.message).toContain("my-existing-skillset");
        expect(mockOutro).not.toHaveBeenCalled();
        expect(mockExit).not.toHaveBeenCalled();
    });
    it("should set type to skillset in nori.json", async () => {
        const existingDir = path.join(skillsetsDir, "type-test-skillset");
        await fs.mkdir(existingDir, { recursive: true });
        mockRegisterSkillsetFlow.mockResolvedValueOnce({
            description: null,
            license: null,
            keywords: null,
            version: null,
            repository: null,
        });
        await registerSkillsetMain({ skillsetName: "type-test-skillset" });
        const noriJson = JSON.parse(await fs.readFile(path.join(existingDir, "nori.json"), "utf-8"));
        expect(noriJson.type).toBe("skillset");
    });
    it("should use current skillset when skillsetName is null", async () => {
        // Create existing skillset directory
        const existingDir = path.join(skillsetsDir, "current-skillset");
        await fs.mkdir(existingDir, { recursive: true });
        // Mock config loading to return current skillset
        mockLoadConfig.mockResolvedValueOnce({ some: "config" });
        mockGetActiveSkillset.mockReturnValueOnce("current-skillset");
        mockRegisterSkillsetFlow.mockResolvedValueOnce({
            description: null,
            license: null,
            keywords: null,
            version: null,
            repository: null,
        });
        await registerSkillsetMain({ skillsetName: null });
        // Verify nori.json was created in the current skillset
        const noriJson = JSON.parse(await fs.readFile(path.join(existingDir, "nori.json"), "utf-8"));
        expect(noriJson.name).toBe("current-skillset");
    });
    it("should return failure status when skillset directory does not exist", async () => {
        const result = await registerSkillsetMain({
            skillsetName: "non-existent-skillset",
        });
        expect(mockLogError).toHaveBeenCalledWith(expect.stringContaining("non-existent-skillset"));
        expect(mockLogError).toHaveBeenCalledWith(expect.stringContaining("does not exist"));
        expect(result.success).toBe(false);
    });
    it("should return failure status when nori.json already exists", async () => {
        // Create existing skillset directory with nori.json
        const existingDir = path.join(skillsetsDir, "already-registered");
        await fs.mkdir(existingDir, { recursive: true });
        await fs.writeFile(path.join(existingDir, "nori.json"), JSON.stringify({ name: "already-registered", version: "1.0.0" }));
        const result = await registerSkillsetMain({
            skillsetName: "already-registered",
        });
        expect(mockLogError).toHaveBeenCalledWith(expect.stringContaining("already-registered"));
        expect(mockLogError).toHaveBeenCalledWith(expect.stringContaining("already has"));
        expect(result.success).toBe(false);
    });
    it("should handle flow cancellation gracefully", async () => {
        // Create existing skillset directory
        const existingDir = path.join(skillsetsDir, "cancel-test");
        await fs.mkdir(existingDir, { recursive: true });
        mockRegisterSkillsetFlow.mockResolvedValueOnce(null);
        await registerSkillsetMain({ skillsetName: "cancel-test" });
        // Verify nori.json was NOT created
        try {
            await fs.access(path.join(existingDir, "nori.json"));
            expect.fail("nori.json should not exist");
        }
        catch {
            // Expected - file should not exist
        }
        expect(mockOutro).not.toHaveBeenCalled();
    });
    it("should use basename for namespaced skillsets", async () => {
        // Create namespaced skillset directory
        const existingDir = path.join(skillsetsDir, "myorg", "namespaced-skillset");
        await fs.mkdir(existingDir, { recursive: true });
        mockRegisterSkillsetFlow.mockResolvedValueOnce({
            description: null,
            license: null,
            keywords: null,
            version: null,
            repository: null,
        });
        await registerSkillsetMain({ skillsetName: "myorg/namespaced-skillset" });
        // Verify nori.json uses basename
        const noriJson = JSON.parse(await fs.readFile(path.join(existingDir, "nori.json"), "utf-8"));
        expect(noriJson.name).toBe("namespaced-skillset");
    });
    it("should write minimal nori.json when all fields are null", async () => {
        const existingDir = path.join(skillsetsDir, "minimal-skillset");
        await fs.mkdir(existingDir, { recursive: true });
        mockRegisterSkillsetFlow.mockResolvedValueOnce({
            description: null,
            license: null,
            keywords: null,
            version: null,
            repository: null,
        });
        await registerSkillsetMain({ skillsetName: "minimal-skillset" });
        const noriJson = JSON.parse(await fs.readFile(path.join(existingDir, "nori.json"), "utf-8"));
        expect(noriJson).toEqual({
            name: "minimal-skillset",
            version: "1.0.0",
            type: "skillset",
        });
    });
    it("should use default version 1.0.0 when version is null", async () => {
        const existingDir = path.join(skillsetsDir, "version-test");
        await fs.mkdir(existingDir, { recursive: true });
        mockRegisterSkillsetFlow.mockResolvedValueOnce({
            description: "Test",
            license: null,
            keywords: null,
            version: null,
            repository: null,
        });
        await registerSkillsetMain({ skillsetName: "version-test" });
        const noriJson = JSON.parse(await fs.readFile(path.join(existingDir, "nori.json"), "utf-8"));
        expect(noriJson.version).toBe("1.0.0");
    });
});
//# sourceMappingURL=registerSkillset.test.js.map