/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { vi } from 'vitest';
vi.mock('node:child_process', async (importOriginal) => {
    const actual = (await importOriginal());
    return {
        ...actual,
        execSync: vi.fn(),
        spawnSync: vi.fn(() => ({ status: 0 })),
    };
});
vi.mock('fs');
vi.mock('os');
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { getIdeInstaller } from './ide-installer.js';
import * as child_process from 'node:child_process';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import { IDE_DEFINITIONS } from './detect-ide.js';
describe('ide-installer', () => {
    const HOME_DIR = '/home/user';
    beforeEach(() => {
        vi.spyOn(os, 'homedir').mockReturnValue(HOME_DIR);
    });
    afterEach(() => {
        vi.restoreAllMocks();
    });
    describe('getIdeInstaller', () => {
        it.each([
            { ide: IDE_DEFINITIONS.vscode },
            { ide: IDE_DEFINITIONS.firebasestudio },
        ])('returns a VsCodeInstaller for "$ide.name"', ({ ide }) => {
            const installer = getIdeInstaller(ide);
            expect(installer).not.toBeNull();
            expect(installer?.install).toEqual(expect.any(Function));
        });
        it('returns an AntigravityInstaller for "antigravity"', () => {
            const installer = getIdeInstaller(IDE_DEFINITIONS.antigravity);
            expect(installer).not.toBeNull();
            expect(installer?.install).toEqual(expect.any(Function));
        });
    });
    describe('VsCodeInstaller', () => {
        function setup({ ide = IDE_DEFINITIONS.vscode, existsResult = false, execSync = () => '', platform = 'linux', } = {}) {
            vi.spyOn(child_process, 'execSync').mockImplementation(execSync);
            vi.spyOn(fs, 'existsSync').mockReturnValue(existsResult);
            const installer = getIdeInstaller(ide, platform);
            return { installer };
        }
        describe('install', () => {
            it.each([
                {
                    platform: 'win32',
                    expectedLookupPaths: [
                        path.join('C:\\Program Files', 'Microsoft VS Code/bin/code.cmd'),
                        path.join(HOME_DIR, '/AppData/Local/Programs/Microsoft VS Code/bin/code.cmd'),
                    ],
                },
                {
                    platform: 'darwin',
                    expectedLookupPaths: [
                        '/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code',
                        path.join(HOME_DIR, 'Library/Application Support/Code/bin/code'),
                    ],
                },
                {
                    platform: 'linux',
                    expectedLookupPaths: ['/usr/share/code/bin/code'],
                },
            ])('identifies the path to code cli on platform: $platform', async ({ platform, expectedLookupPaths }) => {
                const { installer } = setup({
                    platform,
                    execSync: () => {
                        throw new Error('Command not found'); // `code` is not in PATH
                    },
                });
                await installer.install();
                for (const [idx, path] of expectedLookupPaths.entries()) {
                    expect(fs.existsSync).toHaveBeenNthCalledWith(idx + 1, path);
                }
            });
            it('installs the extension using code cli', async () => {
                const { installer } = setup({
                    platform: 'linux',
                });
                await installer.install();
                expect(child_process.spawnSync).toHaveBeenCalledWith('code', [
                    '--install-extension',
                    'google.gemini-cli-vscode-ide-companion',
                    '--force',
                ], { stdio: 'pipe', shell: false });
            });
            it('installs the extension using code cli on windows', async () => {
                const { installer } = setup({
                    platform: 'win32',
                    execSync: () => 'C:\\Program Files\\Microsoft VS Code\\bin\\code.cmd',
                });
                await installer.install();
                expect(child_process.spawnSync).toHaveBeenCalledWith('C:\\Program Files\\Microsoft VS Code\\bin\\code.cmd', [
                    '--install-extension',
                    'google.gemini-cli-vscode-ide-companion',
                    '--force',
                ], { stdio: 'pipe', shell: true });
            });
            it.each([
                {
                    ide: IDE_DEFINITIONS.vscode,
                    expectedMessage: 'VS Code companion extension was installed successfully',
                },
                {
                    ide: IDE_DEFINITIONS.firebasestudio,
                    expectedMessage: 'Firebase Studio companion extension was installed successfully',
                },
            ])('returns that the cli was installed successfully', async ({ ide, expectedMessage }) => {
                const { installer } = setup({ ide });
                const result = await installer.install();
                expect(result.success).toBe(true);
                expect(result.message).toContain(expectedMessage);
            });
            it.each([
                {
                    ide: IDE_DEFINITIONS.vscode,
                    expectedErr: 'VS Code CLI not found',
                },
                {
                    ide: IDE_DEFINITIONS.firebasestudio,
                    expectedErr: 'Firebase Studio CLI not found',
                },
            ])('should return a failure message if $ide is not installed', async ({ ide, expectedErr }) => {
                const { installer } = setup({
                    ide,
                    execSync: () => {
                        throw new Error('Command not found');
                    },
                    existsResult: false,
                });
                const result = await installer.install();
                expect(result.success).toBe(false);
                expect(result.message).toContain(expectedErr);
            });
        });
    });
});
describe('AntigravityInstaller', () => {
    function setup({ execSync = () => '', platform = 'linux', } = {}) {
        vi.spyOn(child_process, 'execSync').mockImplementation(execSync);
        const installer = getIdeInstaller(IDE_DEFINITIONS.antigravity, platform);
        return { installer };
    }
    it('installs the extension using the alias', async () => {
        vi.stubEnv('ANTIGRAVITY_CLI_ALIAS', 'agy');
        const { installer } = setup({});
        const result = await installer.install();
        expect(result.success).toBe(true);
        expect(child_process.spawnSync).toHaveBeenCalledWith('agy', [
            '--install-extension',
            'google.gemini-cli-vscode-ide-companion',
            '--force',
        ], { stdio: 'pipe', shell: false });
    });
    it('returns a failure message if the alias is not set', async () => {
        vi.stubEnv('ANTIGRAVITY_CLI_ALIAS', '');
        const { installer } = setup({});
        const result = await installer.install();
        expect(result.success).toBe(false);
        expect(result.message).toContain('ANTIGRAVITY_CLI_ALIAS environment variable not set');
    });
    it('returns a failure message if the command is not found', async () => {
        vi.stubEnv('ANTIGRAVITY_CLI_ALIAS', 'not-a-command');
        const { installer } = setup({
            execSync: () => {
                throw new Error('Command not found');
            },
        });
        const result = await installer.install();
        expect(result.success).toBe(false);
        expect(result.message).toContain('not-a-command not found');
    });
});
//# sourceMappingURL=ide-installer.test.js.map