/**
 * @license
 * Copyright 2026 HopCode Team
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
import { getSystemInfo, getExtendedSystemInfo, getNpmVersion, getSandboxEnv, getIdeClientName, } from './systemInfo.js';
import { createMockCommandContext } from '../test-utils/mockCommandContext.js';
import * as child_process from 'node:child_process';
import os from 'node:os';
import { IdeClient } from '@hoptrendy/hopcode-core';
import * as versionUtils from './version.js';
vi.mock('node:child_process');
vi.mock('node:os', () => ({
    default: {
        release: vi.fn(),
    },
}));
vi.mock('./version.js', () => ({
    getCliVersion: vi.fn(),
}));
vi.mock('@hoptrendy/hopcode-core', async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        IdeClient: {
            getInstance: vi.fn(),
        },
    };
});
describe('systemInfo', () => {
    let mockContext;
    const originalPlatform = process.platform;
    const originalArch = process.arch;
    const originalVersion = process.version;
    const originalEnv = { ...process.env };
    beforeEach(() => {
        mockContext = createMockCommandContext({
            services: {
                config: {
                    getModel: vi.fn().mockReturnValue('test-model'),
                    getIdeMode: vi.fn().mockReturnValue(true),
                    getSessionId: vi.fn().mockReturnValue('test-session-id'),
                    getAuthType: vi.fn().mockReturnValue('test-auth'),
                    getProxy: vi.fn().mockReturnValue(undefined),
                    getContentGeneratorConfig: vi.fn().mockReturnValue({
                        baseUrl: 'https://api.openai.com',
                    }),
                },
                settings: {
                    merged: {
                        security: {
                            auth: {
                                selectedType: 'test-auth',
                            },
                        },
                    },
                },
            },
        });
        vi.mocked(versionUtils.getCliVersion).mockResolvedValue('test-version');
        vi.mocked(child_process.execSync).mockImplementation((command, options) => {
            if (options &&
                typeof options === 'object' &&
                'encoding' in options &&
                options.encoding === 'utf-8') {
                return '10.0.0';
            }
            return Buffer.from('10.0.0', 'utf-8');
        });
        vi.mocked(os.release).mockReturnValue('22.0.0');
        process.env['GOOGLE_CLOUD_PROJECT'] = 'test-gcp-project';
        Object.defineProperty(process, 'platform', {
            value: 'test-os',
        });
        Object.defineProperty(process, 'arch', {
            value: 'x64',
        });
        Object.defineProperty(process, 'version', {
            value: 'v20.0.0',
        });
    });
    afterEach(() => {
        vi.unstubAllEnvs();
        Object.defineProperty(process, 'platform', {
            value: originalPlatform,
        });
        Object.defineProperty(process, 'arch', {
            value: originalArch,
        });
        Object.defineProperty(process, 'version', {
            value: originalVersion,
        });
        process.env = originalEnv;
        vi.clearAllMocks();
        vi.resetAllMocks();
    });
    describe('getNpmVersion', () => {
        it('should return npm version when available', async () => {
            vi.mocked(child_process.execSync).mockImplementation((command, options) => {
                if (options &&
                    typeof options === 'object' &&
                    'encoding' in options &&
                    options.encoding === 'utf-8') {
                    return '10.0.0';
                }
                return Buffer.from('10.0.0', 'utf-8');
            });
            const version = await getNpmVersion();
            expect(version).toBe('10.0.0');
        });
        it('should return unknown when npm command fails', async () => {
            vi.mocked(child_process.execSync).mockImplementation(() => {
                throw new Error('npm not found');
            });
            const version = await getNpmVersion();
            expect(version).toBe('unknown');
        });
    });
    describe('getSandboxEnv', () => {
        it('should return "no sandbox" when SANDBOX is not set', () => {
            delete process.env['SANDBOX'];
            expect(getSandboxEnv()).toBe('no sandbox');
        });
        it('should return sandbox-exec info when SANDBOX is sandbox-exec', () => {
            process.env['SANDBOX'] = 'sandbox-exec';
            process.env['SEATBELT_PROFILE'] = 'test-profile';
            expect(getSandboxEnv()).toBe('sandbox-exec (test-profile)');
        });
        it('should return sandbox name without prefix when stripPrefix is true', () => {
            process.env['SANDBOX'] = 'hopcode-test-sandbox';
            expect(getSandboxEnv(true)).toBe('test-sandbox');
        });
        it('should return sandbox name with prefix when stripPrefix is false', () => {
            process.env['SANDBOX'] = 'hopcode-test-sandbox';
            expect(getSandboxEnv(false)).toBe('hopcode-test-sandbox');
        });
        it('should handle hopcode- prefix removal', () => {
            process.env['SANDBOX'] = 'hopcode-custom-sandbox';
            expect(getSandboxEnv(true)).toBe('custom-sandbox');
        });
        it('should handle legacy qwen-code- prefix removal', () => {
            process.env['SANDBOX'] = 'qwen-code-test-sandbox';
            expect(getSandboxEnv(true)).toBe('test-sandbox');
        });
        it('should handle legacy qwen- prefix removal', () => {
            process.env['SANDBOX'] = 'qwen-custom-sandbox';
            expect(getSandboxEnv(true)).toBe('custom-sandbox');
        });
    });
    describe('getIdeClientName', () => {
        it('should return IDE client name when IDE mode is enabled', async () => {
            vi.mocked(IdeClient.getInstance).mockResolvedValue({
                getDetectedIdeDisplayName: vi.fn().mockReturnValue('test-ide'),
            });
            const ideClient = await getIdeClientName(mockContext);
            expect(ideClient).toBe('test-ide');
        });
        it('should return empty string when IDE mode is disabled', async () => {
            vi.mocked(mockContext.services.config.getIdeMode).mockReturnValue(false);
            const ideClient = await getIdeClientName(mockContext);
            expect(ideClient).toBe('');
        });
        it('should return empty string when IDE client detection fails', async () => {
            vi.mocked(IdeClient.getInstance).mockRejectedValue(new Error('IDE client error'));
            const ideClient = await getIdeClientName(mockContext);
            expect(ideClient).toBe('');
        });
    });
    describe('getSystemInfo', () => {
        it('should collect all system information', async () => {
            // Ensure SANDBOX is not set for this test
            delete process.env['SANDBOX'];
            vi.mocked(IdeClient.getInstance).mockResolvedValue({
                getDetectedIdeDisplayName: vi.fn().mockReturnValue('test-ide'),
            });
            vi.mocked(child_process.execSync).mockImplementation((command, options) => {
                if (options &&
                    typeof options === 'object' &&
                    'encoding' in options &&
                    options.encoding === 'utf-8') {
                    return '10.0.0';
                }
                return Buffer.from('10.0.0', 'utf-8');
            });
            const systemInfo = await getSystemInfo(mockContext);
            expect(systemInfo).toEqual({
                cliVersion: 'test-version',
                osPlatform: 'test-os',
                osArch: 'x64',
                osRelease: '22.0.0',
                nodeVersion: 'v20.0.0',
                npmVersion: '10.0.0',
                sandboxEnv: 'no sandbox',
                modelVersion: 'test-model',
                selectedAuthType: 'test-auth',
                ideClient: 'test-ide',
                sessionId: 'test-session-id',
                proxy: undefined,
            });
        });
        it('should handle missing config gracefully', async () => {
            mockContext.services.config = null;
            vi.mocked(IdeClient.getInstance).mockResolvedValue({
                getDetectedIdeDisplayName: vi.fn().mockReturnValue(''),
            });
            const systemInfo = await getSystemInfo(mockContext);
            expect(systemInfo.modelVersion).toBe('Unknown');
            expect(systemInfo.sessionId).toBe('unknown');
        });
    });
    describe('getExtendedSystemInfo', () => {
        it('should include memory usage and base URL', async () => {
            vi.mocked(IdeClient.getInstance).mockResolvedValue({
                getDetectedIdeDisplayName: vi.fn().mockReturnValue('test-ide'),
            });
            vi.mocked(child_process.execSync).mockImplementation((command, options) => {
                if (options &&
                    typeof options === 'object' &&
                    'encoding' in options &&
                    options.encoding === 'utf-8') {
                    return '10.0.0';
                }
                return Buffer.from('10.0.0', 'utf-8');
            });
            const { AuthType } = await import('@hoptrendy/hopcode-core');
            // Update the mock context to use OpenAI auth
            mockContext.services.settings.merged.security.auth.selectedType =
                AuthType.USE_OPENAI;
            vi.mocked(mockContext.services.config.getAuthType).mockReturnValue(AuthType.USE_OPENAI);
            const extendedInfo = await getExtendedSystemInfo(mockContext);
            expect(extendedInfo.memoryUsage).toBeDefined();
            expect(extendedInfo.memoryUsage).toMatch(/\d+\.\d+ (KB|MB|GB)/);
            expect(extendedInfo.baseUrl).toBe('https://api.openai.com');
        });
        it('should use sandbox env without prefix for bug reports', async () => {
            process.env['SANDBOX'] = 'hopcode-test-sandbox';
            vi.mocked(IdeClient.getInstance).mockResolvedValue({
                getDetectedIdeDisplayName: vi.fn().mockReturnValue(''),
            });
            vi.mocked(child_process.execSync).mockImplementation((command, options) => {
                if (options &&
                    typeof options === 'object' &&
                    'encoding' in options &&
                    options.encoding === 'utf-8') {
                    return '10.0.0';
                }
                return Buffer.from('10.0.0', 'utf-8');
            });
            const extendedInfo = await getExtendedSystemInfo(mockContext);
            expect(extendedInfo.sandboxEnv).toBe('test-sandbox');
        });
        it('should not include base URL for non-OpenAI auth', async () => {
            vi.mocked(IdeClient.getInstance).mockResolvedValue({
                getDetectedIdeDisplayName: vi.fn().mockReturnValue(''),
            });
            vi.mocked(child_process.execSync).mockImplementation((command, options) => {
                if (options &&
                    typeof options === 'object' &&
                    'encoding' in options &&
                    options.encoding === 'utf-8') {
                    return '10.0.0';
                }
                return Buffer.from('10.0.0', 'utf-8');
            });
            const extendedInfo = await getExtendedSystemInfo(mockContext);
            expect(extendedInfo.baseUrl).toBeUndefined();
        });
    });
});
//# sourceMappingURL=systemInfo.test.js.map