import { describe, it, expect, vi } from 'vitest';
import { executeInit, } from '../../../main/commands/init.command.js';
function createFakeInitDeps(overrides) {
    return {
        log: vi.fn(),
        exit: vi.fn(),
        getConfigDir: vi.fn(() => '/home/user/.config/reviewflow'),
        existsSync: vi.fn(() => false),
        checkPrerequisites: vi.fn(() => ({ status: 'ok' })),
        confirmOverwrite: vi.fn(async () => true),
        promptPlatform: vi.fn(async () => 'both'),
        promptPort: vi.fn(async () => 3847),
        promptGitlabUsername: vi.fn(async () => 'my-gitlab-user'),
        promptGithubUsername: vi.fn(async () => 'my-github-user'),
        confirmScanRepositories: vi.fn(async () => false),
        selectRepositories: vi.fn(async (repos) => repos),
        generateWebhookSecret: vi.fn(() => 'secret-abc-123'),
        truncateSecret: vi.fn((s) => `${s.slice(0, 8)}...`),
        discoverRepositories: vi.fn(() => ({
            repositories: [],
            scannedPaths: [],
            skippedPaths: [],
        })),
        configureMcp: vi.fn(() => 'configured'),
        writeConfig: vi.fn(() => ({
            configPath: '/home/user/.config/reviewflow/config.json',
            envPath: '/home/user/.config/reviewflow/.env',
        })),
        formatSummary: vi.fn(() => 'Summary output'),
        ...overrides,
    };
}
describe('executeInit', () => {
    describe('welcome banner', () => {
        it('should display welcome banner at start', async () => {
            const log = vi.fn();
            const deps = createFakeInitDeps({ log });
            await executeInit(false, false, false, [], deps);
            const firstCall = log.mock.calls[0]?.[0];
            expect(typeof firstCall).toBe('string');
            expect(firstCall).toContain('Welcome to ReviewFlow');
        });
    });
    describe('prerequisites check', () => {
        it('should exit with code 1 when Node version is too low', async () => {
            const exit = vi.fn();
            const log = vi.fn();
            const deps = createFakeInitDeps({
                exit,
                log,
                checkPrerequisites: vi.fn(() => ({
                    status: 'node-version-too-low',
                    found: 18,
                    required: 20,
                })),
            });
            await executeInit(false, false, false, [], deps);
            expect(exit).toHaveBeenCalledWith(1);
            expect(log).toHaveBeenCalledWith(expect.stringContaining('Node.js'));
        });
        it('should exit with code 1 when Claude CLI is not installed', async () => {
            const exit = vi.fn();
            const log = vi.fn();
            const deps = createFakeInitDeps({
                exit,
                log,
                checkPrerequisites: vi.fn(() => ({
                    status: 'claude-not-installed',
                    installUrl: 'https://docs.anthropic.com/en/docs/claude-code/overview',
                })),
            });
            await executeInit(false, false, false, [], deps);
            expect(exit).toHaveBeenCalledWith(1);
            expect(log).toHaveBeenCalledWith(expect.stringContaining('Claude CLI'));
        });
    });
    describe('config overwrite', () => {
        it('should ask to overwrite when config already exists', async () => {
            const confirmOverwrite = vi.fn(async () => false);
            const writeConfig = vi.fn(() => ({
                configPath: '/config.json',
                envPath: '/.env',
            }));
            const deps = createFakeInitDeps({
                existsSync: vi.fn(() => true),
                confirmOverwrite,
                writeConfig,
            });
            await executeInit(false, false, false, [], deps);
            expect(confirmOverwrite).toHaveBeenCalled();
            expect(writeConfig).not.toHaveBeenCalled();
        });
        it('should skip overwrite prompt in --yes mode', async () => {
            const confirmOverwrite = vi.fn(async () => false);
            const writeConfig = vi.fn(() => ({
                configPath: '/config.json',
                envPath: '/.env',
            }));
            const deps = createFakeInitDeps({
                existsSync: vi.fn(() => true),
                confirmOverwrite,
                writeConfig,
            });
            await executeInit(true, false, false, [], deps);
            expect(confirmOverwrite).not.toHaveBeenCalled();
            expect(writeConfig).toHaveBeenCalled();
        });
    });
    describe('platform selection', () => {
        it('should only ask gitlab username when platform is gitlab', async () => {
            const promptGitlabUsername = vi.fn(async () => 'gitlab-user');
            const promptGithubUsername = vi.fn(async () => 'github-user');
            const deps = createFakeInitDeps({
                promptPlatform: vi.fn(async () => 'gitlab'),
                promptGitlabUsername,
                promptGithubUsername,
            });
            await executeInit(false, false, false, [], deps);
            expect(promptGitlabUsername).toHaveBeenCalled();
            expect(promptGithubUsername).not.toHaveBeenCalled();
        });
        it('should only ask github username when platform is github', async () => {
            const promptGitlabUsername = vi.fn(async () => 'gitlab-user');
            const promptGithubUsername = vi.fn(async () => 'github-user');
            const deps = createFakeInitDeps({
                promptPlatform: vi.fn(async () => 'github'),
                promptGitlabUsername,
                promptGithubUsername,
            });
            await executeInit(false, false, false, [], deps);
            expect(promptGitlabUsername).not.toHaveBeenCalled();
            expect(promptGithubUsername).toHaveBeenCalled();
        });
        it('should ask both usernames when platform is both', async () => {
            const promptGitlabUsername = vi.fn(async () => 'gitlab-user');
            const promptGithubUsername = vi.fn(async () => 'github-user');
            const deps = createFakeInitDeps({
                promptPlatform: vi.fn(async () => 'both'),
                promptGitlabUsername,
                promptGithubUsername,
            });
            await executeInit(false, false, false, [], deps);
            expect(promptGitlabUsername).toHaveBeenCalled();
            expect(promptGithubUsername).toHaveBeenCalled();
        });
    });
    describe('--yes mode (non-interactive)', () => {
        it('should use defaults without prompting', async () => {
            const promptPlatform = vi.fn(async () => 'gitlab');
            const promptPort = vi.fn(async () => 9999);
            const writeConfig = vi.fn(() => ({
                configPath: '/config.json',
                envPath: '/.env',
            }));
            const deps = createFakeInitDeps({
                promptPlatform,
                promptPort,
                writeConfig,
            });
            await executeInit(true, false, false, [], deps);
            expect(promptPlatform).not.toHaveBeenCalled();
            expect(promptPort).not.toHaveBeenCalled();
            expect(writeConfig).toHaveBeenCalledWith(expect.objectContaining({
                port: 3847,
                gitlabUsername: '',
                githubUsername: '',
            }));
        });
    });
    describe('secrets generation', () => {
        it('should always generate both secrets regardless of platform', async () => {
            const generateWebhookSecret = vi.fn(() => 'secret-value');
            const writeConfig = vi.fn(() => ({
                configPath: '/config.json',
                envPath: '/.env',
            }));
            const deps = createFakeInitDeps({
                promptPlatform: vi.fn(async () => 'gitlab'),
                generateWebhookSecret,
                writeConfig,
            });
            await executeInit(false, false, false, [], deps);
            expect(generateWebhookSecret).toHaveBeenCalledTimes(2);
            expect(writeConfig).toHaveBeenCalledWith(expect.objectContaining({
                gitlabWebhookSecret: 'secret-value',
                githubWebhookSecret: 'secret-value',
            }));
        });
        it('should display full secrets when showSecrets is true', async () => {
            const log = vi.fn();
            const deps = createFakeInitDeps({
                log,
                generateWebhookSecret: vi.fn(() => 'full-secret-value-here'),
            });
            await executeInit(false, false, true, [], deps);
            const allLogs = log.mock.calls.map(c => c[0]).join('\n');
            expect(allLogs).toContain('GitLab: full-secret-value-here');
            expect(allLogs).toContain('GitHub: full-secret-value-here');
        });
        it('should display truncated secrets when showSecrets is false', async () => {
            const log = vi.fn();
            const truncateSecret = vi.fn(() => 'abc123...');
            const deps = createFakeInitDeps({
                log,
                truncateSecret,
            });
            await executeInit(false, false, false, [], deps);
            expect(truncateSecret).toHaveBeenCalledTimes(2);
            const allLogs = log.mock.calls.map(c => c[0]).join('\n');
            expect(allLogs).toContain('GitLab: abc123...');
            expect(allLogs).toContain('GitHub: abc123...');
        });
    });
    describe('repository scanning', () => {
        it('should skip scan when user declines', async () => {
            const discoverRepositories = vi.fn(() => ({
                repositories: [],
                scannedPaths: [],
                skippedPaths: [],
            }));
            const deps = createFakeInitDeps({
                confirmScanRepositories: vi.fn(async () => false),
                discoverRepositories,
            });
            await executeInit(false, false, false, [], deps);
            expect(discoverRepositories).not.toHaveBeenCalled();
        });
        it('should auto-scan in --yes mode', async () => {
            const discoverRepositories = vi.fn(() => ({
                repositories: [],
                scannedPaths: [],
                skippedPaths: [],
            }));
            const deps = createFakeInitDeps({ discoverRepositories });
            await executeInit(true, false, false, [], deps);
            expect(discoverRepositories).toHaveBeenCalled();
        });
        it('should call selectRepositories with discovered repos in interactive mode', async () => {
            const fakeRepos = [
                { name: 'app-one', localPath: '/projects/app-one', platform: 'github', remoteUrl: 'https://github.com/user/app-one', hasReviewConfig: false },
                { name: 'app-two', localPath: '/projects/app-two', platform: 'gitlab', remoteUrl: 'https://gitlab.com/user/app-two', hasReviewConfig: true },
            ];
            const selectRepositories = vi.fn(async (repos) => [repos[0]]);
            const writeConfig = vi.fn(() => ({
                configPath: '/config.json',
                envPath: '/.env',
            }));
            const deps = createFakeInitDeps({
                confirmScanRepositories: vi.fn(async () => true),
                discoverRepositories: vi.fn(() => ({
                    repositories: fakeRepos,
                    scannedPaths: ['/projects'],
                    skippedPaths: [],
                })),
                selectRepositories,
                writeConfig,
            });
            await executeInit(false, false, false, [], deps);
            expect(selectRepositories).toHaveBeenCalledWith(fakeRepos);
            expect(writeConfig).toHaveBeenCalledWith(expect.objectContaining({
                repositories: [{ name: 'app-one', localPath: '/projects/app-one', enabled: true }],
            }));
        });
    });
    describe('MCP configuration', () => {
        it('should skip MCP when --skip-mcp is set', async () => {
            const configureMcp = vi.fn(() => 'configured');
            const deps = createFakeInitDeps({ configureMcp });
            await executeInit(false, true, false, [], deps);
            expect(configureMcp).not.toHaveBeenCalled();
        });
        it('should configure MCP when --skip-mcp is not set', async () => {
            const configureMcp = vi.fn(() => 'configured');
            const deps = createFakeInitDeps({ configureMcp });
            await executeInit(false, false, false, [], deps);
            expect(configureMcp).toHaveBeenCalled();
        });
    });
    describe('summary output', () => {
        it('should display formatted summary at the end', async () => {
            const log = vi.fn();
            const formatSummary = vi.fn(() => 'Setup complete!');
            const deps = createFakeInitDeps({ log, formatSummary });
            await executeInit(false, false, false, [], deps);
            expect(formatSummary).toHaveBeenCalled();
            expect(log).toHaveBeenCalledWith(expect.stringContaining('Setup complete!'));
        });
    });
});
//# sourceMappingURL=executeInit.test.js.map