/**
 * Configuration Management
 *
 * Manages CV-Git configuration including platform settings, credentials, and features.
 */
import { promises as fs } from 'fs';
import * as path from 'path';
import * as os from 'os';
import { GitPlatform } from '@cv-git/credentials';
const DEFAULT_CONFIG = {
    version: '0.2.0',
    platform: {
        type: GitPlatform.GITHUB,
        url: 'https://github.com',
        api: 'https://api.github.com',
    },
    credentials: {
        storage: 'keychain',
        masterPasswordRequired: false,
    },
    ai: {
        provider: 'anthropic',
        model: 'claude-sonnet-4-5-20250514',
        maxTokens: 128000,
        temperature: 0.7,
    },
    graph: {
        url: 'redis://localhost:6379',
        database: 'cv-graph',
    },
    vector: {
        url: 'http://localhost:6333',
        collection: 'cv-vectors',
    },
    features: {
        aiCommitMessages: true,
        aiPRDescriptions: true,
        aiCodeReview: true,
        autoMerge: false,
    },
    hub: {
        url: 'https://api.hub.controlvector.io/api',
    },
};
export class ConfigManager {
    configPath;
    config = null;
    constructor(configPath) {
        this.configPath =
            configPath || path.join(os.homedir(), '.cv', 'config.json');
    }
    /**
     * Load configuration from file
     */
    async load() {
        if (this.config)
            return this.config;
        try {
            const data = await fs.readFile(this.configPath, 'utf8');
            this.config = JSON.parse(data);
            return this.config;
        }
        catch (error) {
            if (error.code === 'ENOENT') {
                // Config doesn't exist, return default
                this.config = { ...DEFAULT_CONFIG };
                return this.config;
            }
            throw error;
        }
    }
    /**
     * Save configuration to file
     */
    async save(config) {
        this.config = config;
        const dir = path.dirname(this.configPath);
        await fs.mkdir(dir, { recursive: true });
        await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), {
            mode: 0o600,
        });
    }
    /**
     * Update configuration
     */
    async update(updates) {
        const current = await this.load();
        const updated = { ...current, ...updates };
        await this.save(updated);
        return updated;
    }
    /**
     * Get a configuration value
     */
    async get(key) {
        const config = await this.load();
        return config[key];
    }
    /**
     * Set a configuration value
     */
    async set(key, value) {
        const config = await this.load();
        config[key] = value;
        await this.save(config);
    }
    /**
     * Get nested configuration value
     */
    async getNested(path) {
        const config = await this.load();
        const parts = path.split('.');
        let value = config;
        for (const part of parts) {
            if (value && typeof value === 'object' && part in value) {
                value = value[part];
            }
            else {
                return undefined;
            }
        }
        return value;
    }
    /**
     * Set nested configuration value
     */
    async setNested(path, value) {
        const config = await this.load();
        const parts = path.split('.');
        const lastPart = parts.pop();
        let current = config;
        for (const part of parts) {
            if (!(part in current)) {
                current[part] = {};
            }
            current = current[part];
        }
        current[lastPart] = value;
        await this.save(config);
    }
    /**
     * Reset to default configuration
     */
    async reset() {
        this.config = { ...DEFAULT_CONFIG };
        await this.save(this.config);
        return this.config;
    }
    /**
     * Check if config exists
     */
    async exists() {
        try {
            await fs.access(this.configPath);
            return true;
        }
        catch {
            return false;
        }
    }
    /**
     * Initialize configuration (create with defaults)
     */
    async init() {
        const config = { ...DEFAULT_CONFIG };
        await this.save(config);
        return config;
    }
}
/**
 * Get global config instance
 */
let globalConfig = null;
export function getConfig() {
    if (!globalConfig) {
        globalConfig = new ConfigManager();
    }
    return globalConfig;
}
// ============================================================================
// Preferences Manager
// ============================================================================
const DEFAULT_PREFERENCES = {
    version: '1.0.0',
    gitPlatform: 'github',
    aiProvider: 'anthropic',
    embeddingProvider: 'openrouter',
    setupComplete: false,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
};
export class PreferencesManager {
    prefsPath;
    preferences = null;
    constructor(prefsPath) {
        this.prefsPath =
            prefsPath || path.join(os.homedir(), '.cv', 'preferences.json');
    }
    /**
     * Load preferences from file
     */
    async load() {
        if (this.preferences)
            return this.preferences;
        try {
            const data = await fs.readFile(this.prefsPath, 'utf8');
            this.preferences = JSON.parse(data);
            return this.preferences;
        }
        catch (error) {
            if (error.code === 'ENOENT') {
                // Prefs don't exist yet
                return { ...DEFAULT_PREFERENCES };
            }
            throw error;
        }
    }
    /**
     * Save preferences to file
     */
    async save(prefs) {
        this.preferences = {
            ...prefs,
            updatedAt: new Date().toISOString(),
        };
        const dir = path.dirname(this.prefsPath);
        await fs.mkdir(dir, { recursive: true });
        await fs.writeFile(this.prefsPath, JSON.stringify(this.preferences, null, 2), {
            mode: 0o600,
        });
    }
    /**
     * Check if preferences exist
     */
    async exists() {
        try {
            await fs.access(this.prefsPath);
            return true;
        }
        catch {
            return false;
        }
    }
    /**
     * Initialize preferences with user choices
     */
    async init(choices) {
        const prefs = {
            ...DEFAULT_PREFERENCES,
            ...choices,
            setupComplete: true,
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
        };
        await this.save(prefs);
        return prefs;
    }
    /**
     * Update a single preference
     */
    async set(key, value) {
        const prefs = await this.load();
        prefs[key] = value;
        await this.save(prefs);
    }
    /**
     * Get a single preference
     */
    async get(key) {
        const prefs = await this.load();
        return prefs[key];
    }
    /**
     * Reset to defaults
     */
    async reset() {
        this.preferences = {
            ...DEFAULT_PREFERENCES,
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
        };
        await this.save(this.preferences);
        return this.preferences;
    }
    /**
     * Get preferences file path
     */
    getPath() {
        return this.prefsPath;
    }
}
/**
 * Get global preferences instance
 */
let globalPreferences = null;
export function getPreferences() {
    if (!globalPreferences) {
        globalPreferences = new PreferencesManager();
    }
    return globalPreferences;
}
//# sourceMappingURL=config.js.map