/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { EventEmitter } from 'events';
export class SettingsService extends EventEmitter {
    settings;
    eventEmitter;
    constructor() {
        super();
        // Lines 05-14: Initialize in-memory only, no repository parameter
        this.settings = {
            providers: {},
            global: {},
            activeProvider: null,
            tools: {},
        };
        this.eventEmitter = new EventEmitter();
    }
    // Lines 16-23: Direct synchronous access to settings object
    get(key) {
        if (key.includes('.')) {
            return this.getNestedValue(this.settings, key);
        }
        return this.settings.global[key];
    }
    // Lines 25-38: Store old value, update in-memory object, emit change event, NO file writes
    set(key, value) {
        const oldValue = this.get(key);
        if (key.includes('.')) {
            const settingsRecord = this.settings;
            this.setNestedValue(settingsRecord, key, value);
            const [root, ...rest] = key.split('.');
            if (root && root !== 'providers') {
                const rootValue = settingsRecord[root];
                if (rootValue !== undefined) {
                    this.settings.global[root] = rootValue;
                }
                if (rest.length === 0) {
                    this.settings.global[root] = rootValue;
                }
            }
        }
        else {
            this.settings.global[key] = value;
        }
        this.eventEmitter.emit('change', {
            key,
            oldValue,
            newValue: value,
        });
    }
    // Lines 40-54: Provider-specific methods - direct manipulation of settings.providers
    getProviderSettings(provider) {
        return this.settings.providers[provider] || {};
    }
    setProviderSetting(provider, key, value) {
        if (!this.settings.providers[provider]) {
            this.settings.providers[provider] = {};
        }
        const oldValue = this.settings.providers[provider][key];
        this.settings.providers[provider][key] = value;
        this.eventEmitter.emit('provider-change', {
            provider,
            key,
            oldValue,
            newValue: value,
        });
    }
    // Lines 56-64: Clear method - reset to empty state, emit cleared event
    clear() {
        this.settings = {
            providers: {},
            global: {},
            activeProvider: null,
        };
        this.eventEmitter.emit('cleared');
    }
    // Public method to get all global settings
    getAllGlobalSettings() {
        const snapshot = {
            ...this.settings.global,
        };
        if (this.settings.tools) {
            const tools = this.settings.tools;
            snapshot.tools = { ...tools };
            if (Array.isArray(tools.allowed)) {
                snapshot['tools.allowed'] = [...tools.allowed];
            }
            if (Array.isArray(tools.disabled)) {
                snapshot['tools.disabled'] = [...tools.disabled];
            }
        }
        return snapshot;
    }
    // Helper methods for nested key support
    getNestedValue(obj, key) {
        const keys = key.split('.');
        let current = obj;
        for (const k of keys) {
            if (current && typeof current === 'object' && k in current) {
                current = current[k];
            }
            else {
                return undefined;
            }
        }
        return current;
    }
    setNestedValue(obj, key, value) {
        const keys = key.split('.');
        // Security: Check for dangerous keys that can pollute prototypes
        const dangerousKeys = ['__proto__', 'constructor', 'prototype'];
        for (const k of keys) {
            if (dangerousKeys.includes(k)) {
                throw new Error(`Cannot set dangerous property: ${k}`);
            }
        }
        let current = obj;
        for (let i = 0; i < keys.length - 1; i++) {
            const k = keys[i];
            if (!current[k] || typeof current[k] !== 'object') {
                current[k] = {};
            }
            current = current[k];
        }
        current[keys[keys.length - 1]] = value;
    }
    on(event, listener) {
        if (event === 'settings_changed') {
            return this.onSettingsChanged(listener);
        }
        this.eventEmitter.on(event, listener);
        return this;
    }
    off(event, listener) {
        this.eventEmitter.off(event, listener);
        return this;
    }
    getSettings(provider) {
        if (provider === undefined) {
            return Promise.resolve({
                providers: this.settings.providers,
            });
        }
        return Promise.resolve(this.getProviderSettings(provider));
    }
    updateSettings(providerOrChanges, changes) {
        if (typeof providerOrChanges === 'string' && changes) {
            // Provider-specific update
            for (const [key, value] of Object.entries(changes)) {
                this.setProviderSetting(providerOrChanges, key, value);
            }
        }
        else if (providerOrChanges && typeof providerOrChanges === 'object') {
            // Global update
            for (const [key, value] of Object.entries(providerOrChanges)) {
                this.set(key, value);
            }
        }
        return Promise.resolve();
    }
    switchProvider(newProvider) {
        this.set('activeProvider', newProvider);
        return Promise.resolve();
    }
    exportForProfile() {
        // Get activeProvider from global settings first, then fallback to direct field or default
        const activeProvider = this.settings.global.activeProvider ||
            this.settings.activeProvider ||
            'openai';
        const allowedValue = this.get('tools.allowed');
        const disabledValue = this.get('tools.disabled');
        const legacyDisabled = this.get('disabled-tools');
        const allowedTools = Array.isArray(allowedValue)
            ? allowedValue.slice()
            : [];
        const disabledTools = Array.isArray(disabledValue)
            ? disabledValue.slice()
            : Array.isArray(legacyDisabled)
                ? legacyDisabled.slice()
                : [];
        return Promise.resolve({
            defaultProvider: activeProvider,
            providers: this.settings.providers,
            tools: {
                allowed: allowedTools,
                disabled: disabledTools,
            },
        });
    }
    importFromProfile(profileData) {
        // Don't clear ALL settings - just clear provider settings
        // Keep global settings like activeProvider if it's already set correctly
        this.settings.providers = {};
        // Import profile data
        if (profileData && typeof profileData === 'object') {
            const data = profileData;
            // Set the active provider
            if (data.defaultProvider) {
                this.set('activeProvider', data.defaultProvider);
                this.settings.activeProvider = data.defaultProvider;
            }
            // Import provider settings
            if (data.providers) {
                for (const [provider, settings] of Object.entries(data.providers)) {
                    if (settings && typeof settings === 'object') {
                        for (const [key, value] of Object.entries(settings)) {
                            this.setProviderSetting(provider, key, value);
                        }
                    }
                }
            }
            const toolsAllowed = Array.isArray(data.tools?.allowed)
                ? (data.tools?.allowed).map((name) => String(name))
                : [];
            const toolsDisabled = Array.isArray(data.tools?.disabled)
                ? (data.tools?.disabled).map((name) => String(name))
                : [];
            this.settings.tools = this.settings.tools ?? {};
            this.settings.tools['allowed'] =
                toolsAllowed;
            this.settings.tools['disabled'] =
                toolsDisabled;
            this.settings.global['tools'] = {
                allowed: toolsAllowed,
                disabled: toolsDisabled,
            };
            this.settings.global['disabled-tools'] = toolsDisabled;
        }
        return Promise.resolve();
    }
    setCurrentProfileName(profileName) {
        this.set('currentProfile', profileName);
    }
    getCurrentProfileName() {
        return this.get('currentProfile');
    }
    getDiagnosticsData() {
        // Get activeProvider from global settings (set via set() method) or fallback to direct field or default
        const activeProvider = this.settings.global.activeProvider ||
            this.settings.activeProvider ||
            'openai';
        const providerSettings = this.getProviderSettings(activeProvider);
        // Get the model from provider settings, fallback to 'unknown' if not set
        const model = providerSettings.model || 'unknown';
        // Extract model parameters from provider settings (exclude 'model' itself)
        const modelParams = {};
        for (const [key, value] of Object.entries(providerSettings)) {
            if (key !== 'model' && value !== undefined) {
                modelParams[key] = value;
            }
        }
        return Promise.resolve({
            provider: activeProvider,
            model,
            profile: this.getCurrentProfileName(),
            providerSettings,
            ephemeralSettings: this.settings.global,
            modelParams,
            allSettings: {
                providers: this.settings.providers,
            },
        });
    }
    onSettingsChanged(listener) {
        this.eventEmitter.on('settings_changed', listener);
        return () => this.eventEmitter.removeListener('settings_changed', listener);
    }
}
//# sourceMappingURL=SettingsService.js.map