/**
 * @license
 * Copyright 2025 Vybestack LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { Config, ProviderManager, } from '@vybestack/llxprt-code-core';
import { createTempDirectory, cleanupTempDirectory } from './test-utils.js';
describe('Provider Switching Authentication Isolation', () => {
    let tempDir;
    let config;
    let providerManager;
    beforeEach(async () => {
        tempDir = await createTempDirectory();
        // Create a real Config instance
        config = new Config({
            sessionId: 'test-session',
            targetDir: tempDir,
            debugMode: false,
            cwd: tempDir,
            model: 'test-model',
        });
        // Create a real ProviderManager instance
        providerManager = new ProviderManager();
        config.setProviderManager(providerManager);
        await config.initialize();
    });
    afterEach(async () => {
        await cleanupTempDirectory(tempDir);
    });
    it('should isolate API keys between providers', async () => {
        // Create mock providers with API key tracking
        const providerA = createMockProvider('providerA');
        const providerB = createMockProvider('providerB');
        // Register providers
        providerManager.registerProvider(providerA);
        providerManager.registerProvider(providerB);
        // Set API key for provider A
        providerManager.setActiveProvider('providerA');
        config.setEphemeralSetting('apiKey', 'key-for-provider-a');
        providerA.setApiKey?.('key-for-provider-a');
        // Note: Provider apiKey is internal, we verify through config instead
        expect(config.getEphemeralSetting('apiKey')).toBe('key-for-provider-a');
        // Switch to provider B with different key
        providerManager.setActiveProvider('providerB');
        config.setEphemeralSetting('apiKey', 'key-for-provider-b');
        providerB.setApiKey?.('key-for-provider-b');
        // Note: Provider apiKey is internal, we verify through config instead
        expect(config.getEphemeralSetting('apiKey')).toBe('key-for-provider-b');
        // Switch back to provider A
        providerManager.setActiveProvider('providerA');
        // Note: Provider A's state was cleared
        // The ephemeral setting remains from provider B (no automatic clearing in Config)
        expect(config.getEphemeralSetting('apiKey')).toBe('key-for-provider-b');
    });
    it('should clear ephemeral settings on provider switch', async () => {
        // Create mock providers
        const providerA = createMockProvider('providerA');
        const providerB = createMockProvider('providerB');
        // Register providers
        providerManager.registerProvider(providerA);
        providerManager.registerProvider(providerB);
        // Set ephemeral settings for provider A
        providerManager.setActiveProvider('providerA');
        config.setEphemeralSetting('apiKey', 'test-key-a');
        config.setEphemeralSetting('baseUrl', 'https://api.provider-a.com');
        config.setEphemeralSetting('customSetting', 'value-a');
        // Verify settings are set
        expect(config.getEphemeralSetting('apiKey')).toBe('test-key-a');
        expect(config.getEphemeralSetting('baseUrl')).toBe('https://api.provider-a.com');
        expect(config.getEphemeralSetting('customSetting')).toBe('value-a');
        // Switch to provider B
        providerManager.setActiveProvider('providerB');
        // Manual clearing of ephemeral settings (since Config doesn't auto-clear)
        // In real usage, the CLI would handle this
        const ephemeralSettings = config.getEphemeralSettings();
        Object.keys(ephemeralSettings).forEach((key) => {
            config.setEphemeralSetting(key, undefined);
        });
        // Verify all ephemeral settings are cleared
        expect(config.getEphemeralSetting('apiKey')).toBeUndefined();
        expect(config.getEphemeralSetting('baseUrl')).toBeUndefined();
        expect(config.getEphemeralSetting('customSetting')).toBeUndefined();
    });
    it('should clear model parameters on provider switch', async () => {
        // Create mock providers with model parameter support
        const providerA = createMockProvider('providerA');
        const providerB = createMockProvider('providerB');
        // Register providers
        providerManager.registerProvider(providerA);
        providerManager.registerProvider(providerB);
        // Set model params for provider A
        providerManager.setActiveProvider('providerA');
        const paramsA = {
            temperature: 0.7,
            maxTokens: 1000,
            topP: 0.9,
        };
        providerA.setModelParams?.(paramsA);
        // Verify provider A has params
        expect(providerA.getModelParams?.()).toEqual(paramsA);
        // Switch to provider B
        providerManager.setActiveProvider('providerB');
        // Verify provider A's state is cleared (including model params)
        expect(providerA.getModelParams?.()).toBeUndefined();
        // Set different params for provider B
        const paramsB = {
            temperature: 0.5,
            maxTokens: 2000,
            frequencyPenalty: 0.1,
        };
        providerB.setModelParams?.(paramsB);
        // Verify provider B has its own params
        expect(providerB.getModelParams?.()).toEqual(paramsB);
        // Switch back to provider A
        providerManager.setActiveProvider('providerA');
        // Verify provider B's state is cleared
        expect(providerB.getModelParams?.()).toBeUndefined();
    });
    it('should verify API keys are ephemeral and not persisted', async () => {
        // Create a mock provider
        const provider = createMockProvider('testProvider');
        providerManager.registerProvider(provider);
        // Set as active and add API key
        providerManager.setActiveProvider('testProvider');
        config.setEphemeralSetting('apiKey', 'ephemeral-test-key');
        provider.setApiKey?.('ephemeral-test-key');
        // Verify key is in ephemeral settings
        expect(config.getEphemeralSetting('apiKey')).toBe('ephemeral-test-key');
        // Verify key is NOT in any persistent storage
        // The config object doesn't expose persistent settings directly,
        // but we can verify that ephemeral settings are separate
        const allEphemeralSettings = config.getEphemeralSettings();
        expect(allEphemeralSettings['apiKey']).toBe('ephemeral-test-key');
        // Create a new Config instance to simulate restart
        const newConfig = new Config({
            sessionId: 'new-session',
            targetDir: tempDir,
            debugMode: false,
            cwd: tempDir,
            model: 'test-model',
        });
        await newConfig.initialize();
        // Verify API key is not persisted
        expect(newConfig.getEphemeralSetting('apiKey')).toBeUndefined();
    });
    it('should handle server tools provider separately from active provider', async () => {
        // Create mock providers
        const geminiProvider = createMockProvider('gemini');
        geminiProvider.getServerTools = () => ['web-search'];
        const otherProvider = createMockProvider('other');
        // Register providers
        providerManager.registerProvider(geminiProvider);
        providerManager.registerProvider(otherProvider);
        // Set Gemini as server tools provider
        providerManager.setServerToolsProvider(geminiProvider);
        // Set other provider as active
        providerManager.setActiveProvider('other');
        config.setEphemeralSetting('apiKey', 'other-provider-key');
        otherProvider.setApiKey?.('other-provider-key');
        // Set API key for Gemini (server tools)
        geminiProvider.setApiKey?.('gemini-server-tools-key');
        // Note: Provider apiKeys are internal, authentication is handled internally
        // Switch active provider to Gemini
        providerManager.setActiveProvider('gemini');
        // Note: Provider state management is handled internally
    });
});
// Helper function to create a mock provider
function createMockProvider(name) {
    const provider = {
        name,
        apiKey: undefined,
        modelParams: undefined,
        state: {},
        setApiKey(key) {
            provider.apiKey = key;
        },
        setModelParams(params) {
            provider.modelParams = params;
        },
        getModelParams() {
            return provider.modelParams;
        },
        clearState() {
            provider.apiKey = undefined;
            provider.modelParams = undefined;
            provider.state = {};
        },
        getModels: async () => [
            {
                id: 'test-model',
                name: 'Test Model',
                provider: name,
                supportedToolFormats: [],
            },
        ],
        getDefaultModel: () => 'test-model',
        async *generateChatCompletion() {
            yield {
                speaker: 'ai',
                blocks: [{ type: 'text', text: 'test response' }],
            };
        },
        getServerTools: () => [],
        invokeServerTool: async () => ({ result: 'test' }),
    };
    return provider;
}
//# sourceMappingURL=provider-switching.integration.test.js.map