/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as os from 'node:os';
import { ExtensionManager } from './extension-manager.js';
import { createTestMergedSettings } from './settings.js';
import { loadAgentsFromDirectory, loadSkillsFromDir, } from '@google/gemini-cli-core';
let currentTempHome = '';
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        homedir: () => currentTempHome,
        debugLogger: {
            log: vi.fn(),
            error: vi.fn(),
            warn: vi.fn(),
        },
        loadAgentsFromDirectory: vi.fn().mockImplementation(async () => ({
            agents: [],
            errors: [],
        })),
        loadSkillsFromDir: vi.fn().mockImplementation(async () => []),
    };
});
describe('ExtensionManager Settings Scope', () => {
    const extensionName = 'test-extension';
    let tempWorkspace;
    let extensionsDir;
    let extensionDir;
    beforeEach(async () => {
        vi.mocked(loadAgentsFromDirectory).mockResolvedValue({
            agents: [],
            errors: [],
        });
        vi.mocked(loadSkillsFromDir).mockResolvedValue([]);
        currentTempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gemini-cli-test-home-'));
        tempWorkspace = fs.mkdtempSync(path.join(os.tmpdir(), 'gemini-cli-test-workspace-'));
        extensionsDir = path.join(currentTempHome, '.gemini', 'extensions');
        extensionDir = path.join(extensionsDir, extensionName);
        fs.mkdirSync(extensionDir, { recursive: true });
        // Create gemini-extension.json
        const extensionConfig = {
            name: extensionName,
            version: '1.0.0',
            settings: [
                {
                    name: 'Test Setting',
                    envVar: 'TEST_SETTING',
                    description: 'A test setting',
                },
            ],
        };
        fs.writeFileSync(path.join(extensionDir, 'gemini-extension.json'), JSON.stringify(extensionConfig));
        // Create install metadata
        const installMetadata = {
            source: extensionDir,
            type: 'local',
        };
        fs.writeFileSync(path.join(extensionDir, 'install-metadata.json'), JSON.stringify(installMetadata));
    });
    afterEach(() => {
        // Clean up files if needed, or rely on temp dir cleanup
        vi.clearAllMocks();
    });
    it('should prioritize workspace settings over user settings and report correct scope', async () => {
        // 1. Set User Setting
        const userSettingsPath = path.join(extensionDir, '.env');
        fs.writeFileSync(userSettingsPath, 'TEST_SETTING=user-value');
        // 2. Set Workspace Setting
        const workspaceSettingsPath = path.join(tempWorkspace, '.env');
        fs.writeFileSync(workspaceSettingsPath, 'TEST_SETTING=workspace-value');
        const extensionManager = new ExtensionManager({
            workspaceDir: tempWorkspace,
            requestConsent: async () => true,
            requestSetting: async () => '',
            settings: createTestMergedSettings({
                telemetry: { enabled: false },
                experimental: { extensionConfig: true },
                security: { folderTrust: { enabled: false } },
            }),
        });
        const extensions = await extensionManager.loadExtensions();
        const extension = extensions.find((e) => e.name === extensionName);
        expect(extension).toBeDefined();
        // Verify resolved settings
        const setting = extension?.resolvedSettings?.find((s) => s.envVar === 'TEST_SETTING');
        expect(setting).toBeDefined();
        expect(setting?.value).toBe('workspace-value');
        expect(setting?.scope).toBe('workspace');
        expect(setting?.source).toBe(workspaceSettingsPath);
        // Verify output string contains (Workspace - <path>)
        const output = extensionManager.toOutputString(extension);
        expect(output).toContain(`Test Setting: workspace-value (Workspace - ${workspaceSettingsPath})`);
    });
    it('should fallback to user settings if workspace setting is missing', async () => {
        // 1. Set User Setting
        const userSettingsPath = path.join(extensionDir, '.env');
        fs.writeFileSync(userSettingsPath, 'TEST_SETTING=user-value');
        // 2. No Workspace Setting
        const extensionManager = new ExtensionManager({
            workspaceDir: tempWorkspace,
            requestConsent: async () => true,
            requestSetting: async () => '',
            settings: createTestMergedSettings({
                telemetry: { enabled: false },
                experimental: { extensionConfig: true },
                security: { folderTrust: { enabled: false } },
            }),
        });
        const extensions = await extensionManager.loadExtensions();
        const extension = extensions.find((e) => e.name === extensionName);
        expect(extension).toBeDefined();
        // Verify resolved settings
        const setting = extension?.resolvedSettings?.find((s) => s.envVar === 'TEST_SETTING');
        expect(setting).toBeDefined();
        expect(setting?.value).toBe('user-value');
        expect(setting?.scope).toBe('user');
        expect(setting?.source?.endsWith(path.join(extensionName, '.env'))).toBe(true);
        // Verify output string contains (User - <path>)
        const output = extensionManager.toOutputString(extension);
        expect(output).toContain(`Test Setting: user-value (User - ${userSettingsPath})`);
    });
    it('should report unset if neither is present', async () => {
        // No settings files
        const extensionManager = new ExtensionManager({
            workspaceDir: tempWorkspace,
            requestConsent: async () => true,
            requestSetting: async () => '',
            settings: createTestMergedSettings({
                telemetry: { enabled: false },
                experimental: { extensionConfig: true },
                security: { folderTrust: { enabled: false } },
            }),
        });
        const extensions = await extensionManager.loadExtensions();
        const extension = extensions.find((e) => e.name === extensionName);
        expect(extension).toBeDefined();
        // Verify resolved settings
        const setting = extension?.resolvedSettings?.find((s) => s.envVar === 'TEST_SETTING');
        expect(setting).toBeDefined();
        expect(setting?.value).toBeUndefined();
        expect(setting?.scope).toBeUndefined();
        // Verify output string does not contain scope
        const output = extensionManager.toOutputString(extension);
        expect(output).toContain('Test Setting: [not set]');
        expect(output).not.toContain('Test Setting: [not set] (User)');
        expect(output).not.toContain('Test Setting: [not set] (Workspace)');
    });
});
//# sourceMappingURL=extension-manager-scope.test.js.map