"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
jest.mock("../../../src/config", () => ({
    getConfig: jest.fn().mockResolvedValue({ modules: [] }),
    getGlobalConfig: jest.fn().mockResolvedValue({ modules: [] }),
    getConfigSync: jest.fn().mockReturnValue({}),
    migrateConfig: jest.fn().mockResolvedValue(undefined),
}));
jest.mock("../../../src/clients", () => ({
    AIClient: jest.fn(),
    Clients: { registerClient: jest.fn(), registerModels: jest.fn() },
}));
jest.mock("../../../src/services/KnowhowClient", () => ({
    KnowhowSimpleClient: jest.fn().mockImplementation(() => ({
        getGitCredential: jest.fn().mockResolvedValue({
            protocol: "https",
            host: "github.com",
            username: "x-access-token",
            password: "ghu_TESTTOKEN123",
        }),
    })),
}));
jest.mock("readline", () => ({
    createInterface: jest.fn().mockReturnValue({
        on: jest.fn().mockImplementation(function (event, cb) {
            if (event === "close") {
                setImmediate(() => cb());
            }
            return this;
        }),
    }),
}));
const commander_1 = require("commander");
const misc_1 = require("../../../src/commands/misc");
const logger_1 = require("../../../src/logger");
describe("github-credentials command", () => {
    describe("early silencing (pre-module-load)", () => {
        beforeEach(() => {
            logger_1.logger.unsilence();
            logger_1.logger.installConsoleOverload();
        });
        afterEach(() => {
            logger_1.logger.unsilence();
            logger_1.logger.uninstallConsoleOverload();
        });
        it("silences before module loading when github-credentials is in argv", () => {
            const originalArgv = process.argv;
            process.argv = ["node", "knowhow", "github-credentials", "get"];
            const rawArgs = process.argv.slice(2);
            const SILENT_COMMANDS = ["github-credentials"];
            if (rawArgs.some((a) => SILENT_COMMANDS.includes(a))) {
                logger_1.logger.silence();
            }
            const consoleSpy = jest.spyOn(process.stdout, "write");
            console.log("some module loading noise that should be suppressed");
            expect(consoleSpy).not.toHaveBeenCalled();
            consoleSpy.mockRestore();
            process.argv = originalArgv;
        });
        it("does NOT silence for other commands", () => {
            const originalArgv = process.argv;
            process.argv = ["node", "knowhow", "chat"];
            const rawArgs = process.argv.slice(2);
            const SILENT_COMMANDS = ["github-credentials"];
            if (rawArgs.some((a) => SILENT_COMMANDS.includes(a))) {
                logger_1.logger.silence();
            }
            expect(logger_1.logger.isSilenced()).toBe(false);
            process.argv = originalArgv;
        });
    });
    let program;
    let stdoutSpy;
    let writtenToStdout;
    beforeEach(() => {
        jest.clearAllMocks();
        logger_1.logger.unsilence();
        writtenToStdout = [];
        stdoutSpy = jest
            .spyOn(process.stdout, "write")
            .mockImplementation((chunk) => {
            writtenToStdout.push(typeof chunk === "string" ? chunk : chunk.toString());
            return true;
        });
        program = new commander_1.Command();
        program.exitOverride();
        (0, misc_1.addGithubCredentialsCommand)(program);
    });
    afterEach(() => {
        stdoutSpy.mockRestore();
        logger_1.logger.unsilence();
    });
    it("outputs only credential lines to stdout for 'get' action", async () => {
        await program.parseAsync([
            "node", "knowhow", "github-credentials", "get", "--repo", "myorg/myrepo",
        ]);
        expect(writtenToStdout).toHaveLength(1);
        expect(writtenToStdout[0]).toBe("protocol=https\nhost=github.com\nusername=x-access-token\npassword=ghu_TESTTOKEN123\n");
    });
    it("silences the logger immediately so module logs don't pollute stdout", async () => {
        await program.parseAsync([
            "node", "knowhow", "github-credentials", "get", "--repo", "myorg/myrepo",
        ]);
        expect(logger_1.logger.isSilenced()).toBe(true);
    });
    it("produces exactly 4 credential field lines and nothing else", async () => {
        await program.parseAsync([
            "node", "knowhow", "github-credentials", "get", "--repo", "myorg/myrepo",
        ]);
        const allOutput = writtenToStdout.join("");
        const lines = allOutput.trim().split("\n");
        expect(lines).toHaveLength(4);
        expect(lines[0]).toMatch(/^protocol=/);
        expect(lines[1]).toMatch(/^host=/);
        expect(lines[2]).toMatch(/^username=/);
        expect(lines[3]).toMatch(/^password=/);
    });
    it("exits cleanly for 'store' action without writing credentials", async () => {
        let exitCode;
        const exitSpy = jest
            .spyOn(process, "exit")
            .mockImplementation(((code) => {
            exitCode = code ?? 0;
            throw new Error(`process.exit(${exitCode})`);
        }));
        await expect(program.parseAsync(["node", "knowhow", "github-credentials", "store"])).rejects.toThrow("process.exit(0)");
        expect(exitCode).toBe(0);
        expect(writtenToStdout).toHaveLength(0);
        exitSpy.mockRestore();
    });
    it("exits cleanly for 'erase' action without writing credentials", async () => {
        let exitCode;
        const exitSpy = jest
            .spyOn(process, "exit")
            .mockImplementation(((code) => {
            exitCode = code ?? 0;
            throw new Error(`process.exit(${exitCode})`);
        }));
        await expect(program.parseAsync(["node", "knowhow", "github-credentials", "erase"])).rejects.toThrow("process.exit(0)");
        expect(exitCode).toBe(0);
        expect(writtenToStdout).toHaveLength(0);
        exitSpy.mockRestore();
    });
});
//# sourceMappingURL=github-credentials.test.js.map