/**
 * MCP server configuration — scans multiple locations in precedence order.
 */
import { existsSync, readFileSync } from 'fs';
import { join } from 'path';
import { logger } from '../utils/logger.js';
import { summarizeError } from '../utils/error-display.js';
/**
 * loadMcpConfig - Scan multiple locations in precedence order (later wins).
 * Returns merged config from all found files. Returns empty config on failure.
 */
export function loadMcpConfig(roots) {
    const cwd = roots.workingDirectory;
    const home = roots.homeDirectory;
    // Scan locations in precedence order (later wins)
    const locations = [
        join(home, '.config', 'mcp', 'mcp.json'), // global XDG
        join(home, '.mcp', 'mcp.json'), // global dotdir
        join(home, '.config', 'claude', 'claude_desktop_config.json'), // Claude Desktop
        join(cwd, '.mcp', 'mcp.json'), // project-local
        join(cwd, '.goodvibes', 'mcp.json'), // goodvibes project
    ];
    const merged = { servers: [] };
    const serversByName = new Map();
    for (const path of locations) {
        try {
            if (!existsSync(path))
                continue;
            const raw = JSON.parse(readFileSync(path, 'utf-8'));
            // Handle Claude Desktop format
            if (typeof raw === 'object' && raw !== null && 'mcpServers' in raw) {
                const obj = raw;
                if (typeof obj['mcpServers'] === 'object' && obj['mcpServers'] !== null) {
                    for (const [name, srv] of Object.entries(obj['mcpServers'])) {
                        const s = srv;
                        if (typeof s.command === 'string') {
                            serversByName.set(name, {
                                name,
                                command: s.command,
                                args: Array.isArray(s.args) ? s.args.filter((a) => typeof a === 'string') : [],
                                env: typeof s.env === 'object' && s.env ? Object.fromEntries(Object.entries(s.env).filter(([, v]) => typeof v === 'string')) : undefined,
                                role: typeof s.role === 'string' ? s.role : undefined,
                                trustMode: typeof s.trustMode === 'string' ? s.trustMode : undefined,
                                allowedPaths: Array.isArray(s.allowedPaths) ? s.allowedPaths.filter((v) => typeof v === 'string') : undefined,
                                allowedHosts: Array.isArray(s.allowedHosts) ? s.allowedHosts.filter((v) => typeof v === 'string') : undefined,
                            });
                        }
                    }
                }
                continue;
            }
            // Handle goodvibes format
            if (isMcpConfig(raw)) {
                for (const srv of raw.servers) {
                    serversByName.set(srv.name, srv);
                }
            }
        }
        catch (err) {
            logger.warn(`[MCP] Failed to read ${path}`, { error: summarizeError(err) });
        }
    }
    merged.servers = [...serversByName.values()];
    return merged;
}
/** Type guard for McpConfig (goodvibes format) */
function isMcpConfig(v) {
    if (typeof v !== 'object' || v === null)
        return false;
    const obj = v;
    if (!Array.isArray(obj['servers']))
        return false;
    for (const s of obj['servers']) {
        if (typeof s !== 'object' || s === null)
            return false;
        const srv = s;
        if (typeof srv['name'] !== 'string' || !srv['name'])
            return false;
        if (typeof srv['command'] !== 'string' || !srv['command'])
            return false;
        if (srv['args'] !== undefined) {
            if (!Array.isArray(srv['args']))
                return false;
            if (!srv['args'].every((a) => typeof a === 'string'))
                return false;
        }
        if (srv['env'] !== undefined && (typeof srv['env'] !== 'object' || srv['env'] === null))
            return false;
        if (srv['role'] !== undefined && typeof srv['role'] !== 'string')
            return false;
        if (srv['trustMode'] !== undefined && typeof srv['trustMode'] !== 'string')
            return false;
        if (srv['allowedPaths'] !== undefined && (!Array.isArray(srv['allowedPaths']) || !srv['allowedPaths'].every((a) => typeof a === 'string')))
            return false;
        if (srv['allowedHosts'] !== undefined && (!Array.isArray(srv['allowedHosts']) || !srv['allowedHosts'].every((a) => typeof a === 'string')))
            return false;
    }
    return true;
}
