/**
 * MCP 工具函数
 *
 * 提供 MCP 服务器配置的构建、转换和规范化功能
 */
import path from 'node:path';
import { randomUUID } from 'node:crypto';
import { parseBoolean } from './validation.js';
/**
 * 构建 MCP 配置内容
 *
 * @param mcpServers - MCP 服务器列表
 * @returns JSON 格式的配置内容
 */
export function buildMcpConfigContent(mcpServers) {
    const servers = Array.isArray(mcpServers) ? mcpServers : [];
    const serverMap = {};
    for (const item of servers) {
        if (!item) {
            continue;
        }
        if (!parseBoolean(item.enabled, true)) {
            continue;
        }
        const name = String(item.name || '').trim();
        if (!name) {
            continue;
        }
        const transport = String(item.transport || 'stdio').trim().toLowerCase();
        const serverCfg = { transport };
        if (item.command != null && String(item.command).trim()) {
            serverCfg.command = String(item.command).trim();
        }
        if (item.url != null && String(item.url).trim()) {
            serverCfg.url = String(item.url).trim();
        }
        if (item.args != null) {
            serverCfg.args = Array.isArray(item.args) ? item.args : [];
        }
        if (item.env != null && typeof item.env === 'object') {
            serverCfg.env = item.env;
        }
        serverMap[name] = serverCfg;
    }
    return JSON.stringify({
        mcpServers: serverMap,
    }, null, 2);
}
/**
 * 规范化 MCP Payload
 *
 * @param payload - 原始 payload
 * @returns 规范化后的 MCP Payload，无效返回 null
 */
export function normalizeMcpPayload(payload) {
    if (!payload || typeof payload !== 'object') {
        return null;
    }
    const p = payload;
    const name = String(p.name || '').trim();
    if (!name) {
        return null;
    }
    return {
        id: String(p.id || randomUUID()),
        name,
        transport: String(p.transport || 'stdio').trim().toLowerCase(),
        command: p.command == null ? '' : String(p.command),
        url: p.url == null ? '' : String(p.url),
        args: Array.isArray(p.args) ? p.args.map((item) => String(item)) : [],
        env: p.env && typeof p.env === 'object' ? p.env : {},
        enabled: parseBoolean(p.enabled, true),
        installedAt: p.installedAt || new Date().toISOString(),
    };
}
/**
 * 规范化 SDK App 标志
 *
 * @param rawApps - 原始 apps 配置
 * @returns 规范化后的 SdkApps
 */
export function normalizeSdkAppFlags(rawApps) {
    if (!rawApps || typeof rawApps !== 'object') {
        return undefined;
    }
    const apps = rawApps;
    const claudecode = parseBoolean(apps.claudecode, false) || parseBoolean(apps.claude, false);
    return {
        claude: false,
        claudecode,
        codex: parseBoolean(apps.codex, false),
        gemini: parseBoolean(apps.gemini, false),
        opencode: parseBoolean(apps.opencode, false),
        openclaw: parseBoolean(apps.openclaw, false),
    };
}
/**
 * 规范化 SDK MCP 服务器规格
 *
 * @param rawMcp - 原始 MCP 配置
 * @returns 规范化后的服务器配置
 */
export function normalizeSdkMcpServerSpec(rawMcp) {
    const mcp = rawMcp && typeof rawMcp === 'object' ? rawMcp : {};
    const baseServer = mcp.server && typeof mcp.server === 'object'
        ? mcp.server
        : {};
    const type = String(baseServer.type || mcp.transport || 'stdio').trim().toLowerCase();
    const server = {
        ...baseServer,
        type,
    };
    if (mcp.command != null && String(mcp.command).trim()) {
        server.command = String(mcp.command).trim();
    }
    if (mcp.url != null && String(mcp.url).trim()) {
        server.url = String(mcp.url).trim();
    }
    if (mcp.args != null) {
        server.args = Array.isArray(mcp.args) ? mcp.args.map((item) => String(item)) : [];
    }
    if (mcp.env != null && typeof mcp.env === 'object') {
        server.env = mcp.env;
    }
    if (mcp.headers != null && typeof mcp.headers === 'object') {
        server.headers = mcp.headers;
    }
    return server;
}
/**
 * 转换为 Legacy MCP State Item
 *
 * @param mcpServer - SDK MCP 服务器对象
 * @returns Legacy MCP State Item
 */
export function toLegacyMcpStateItem(mcpServer) {
    const server = mcpServer?.server && typeof mcpServer.server === 'object' ? mcpServer.server : {};
    const apps = mcpServer?.apps && typeof mcpServer.apps === 'object' ? mcpServer.apps : {};
    return {
        id: String(mcpServer?.id || randomUUID()),
        name: String(mcpServer?.name || '').trim(),
        transport: String(server.type || 'stdio').trim().toLowerCase(),
        command: server.command == null ? '' : String(server.command),
        url: server.url == null ? '' : String(server.url),
        args: Array.isArray(server.args) ? server.args.map((item) => String(item)) : [],
        env: server.env && typeof server.env === 'object' ? server.env : {},
        enabled: Boolean(apps.claudecode || apps.codex || apps.gemini || apps.opencode || apps.openclaw),
        apps: {
            claude: false,
            claudecode: Boolean(apps.claudecode),
            codex: Boolean(apps.codex),
            gemini: Boolean(apps.gemini),
            opencode: Boolean(apps.opencode),
            openclaw: Boolean(apps.openclaw),
        },
        installedAt: new Date().toISOString(),
    };
}
/**
 * 转换为 Legacy Skill State Item
 *
 * @param skill - Skill 对象
 * @returns Legacy Skill State Item
 */
export function toLegacySkillStateItem(skill) {
    const directory = String(skill?.directory || skill?.sourceDir || skill?.filePath || '').trim();
    const apps = skill?.apps && typeof skill.apps === 'object' ? skill.apps : {};
    return {
        id: String(skill?.id || randomUUID()),
        name: String(skill?.name || path.basename(directory || 'skill')).trim(),
        fileName: directory ? path.basename(directory) : '',
        filePath: directory,
        bytes: 0,
        apps: {
            claude: false,
            claudecode: Boolean(apps.claudecode),
            codex: Boolean(apps.codex),
            gemini: Boolean(apps.gemini),
            opencode: Boolean(apps.opencode),
            openclaw: Boolean(apps.openclaw),
        },
        installedAt: skill?.installedAt ? new Date(skill.installedAt).toISOString() : new Date().toISOString(),
    };
}
