/**
 * 知识图谱 MCP 工具
 *
 * harmonyos_graph_search    — 搜索图谱节点
 * harmonyos_graph_neighbors — 获取节点邻居
 * harmonyos_graph_path     — 查找两节点间路径
 * harmonyos_graph_stats    — 图谱统计
 */
import { z } from 'zod';
import { graphSearch, graphNeighbors, graphPath, graphStats, getAllNodeIds, } from '../lib/graph.js';
import { guardKnowledge } from './setup.js';
// ============================================================
// 格式化辅助
// ============================================================
const TYPE_EMOJI = {
    kit: '📦',
    module: '📡',
    component: '🧩',
    guide: '📖',
    error_code: '⚠️',
};
const RELATION_LABEL = {
    belongs_to: '属于 →',
    contains: '包含 →',
    references: '引用 →',
    related: '关联 →',
};
function formatNode(n) {
    const emoji = TYPE_EMOJI[n.type] || '•';
    return `${emoji} **${n.name}** \`${n.id}\``;
}
function formatEdge(e) {
    const label = RELATION_LABEL[e.relation] || e.relation;
    return `\`${e.from}\` ${label} \`${e.to}\``;
}
// ============================================================
// harmonyos_graph_search
// ============================================================
const GraphSearchSchema = z.object({
    query: z.string()
        .min(1, '查询不能为空')
        .describe('搜索关键词,匹配节点名称或 ID。如 "Canvas"、"@ohos.app.ability"、"ArkUI"'),
    type: z.enum(['kit', 'module', 'component', 'guide', 'error_code'])
        .optional()
        .describe('限定节点类型'),
    maxResults: z.number().int().min(1).max(100).default(30)
        .describe('最大结果数'),
}).strict();
export function registerGraphSearchTool(server) {
    server.registerTool('harmonyos_graph_search', {
        title: 'Search Knowledge Graph',
        description: `在 HarmonyOS 知识图谱中搜索节点。

知识图谱包含 Kit、API 模块、UI 组件、开发指南等节点及其关系。

**节点类型:**
- kit: HarmonyOS Kit(AbilityKit, ArkUI, ArkTS...)
- module: @ohos.* API 模块
- component: ArkUI 组件(Button, List, Canvas...)
- guide: 开发指南章节

**使用场景:**
- 查找某个 API 模块属于哪个 Kit
- 发现与某个组件相关的所有模块
- 了解 Kit 的组成结构`,
        inputSchema: GraphSearchSchema,
        annotations: {
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: true,
        },
    }, async (params) => {
        const guard = guardKnowledge();
        if (guard)
            return { content: [{ type: 'text', text: guard }] };
        const results = graphSearch(params.query, {
            type: params.type,
            maxResults: params.maxResults,
        });
        if (results.length === 0) {
            return {
                content: [{ type: 'text', text: `未找到匹配 "${params.query}" 的图谱节点。` }],
            };
        }
        const lines = [
            `# 图谱搜索: "${params.query}"`,
            '',
            `找到 ${results.length} 个节点:`,
            '',
        ];
        for (const n of results) {
            lines.push(formatNode(n));
            if (n.path)
                lines.push(`  📁 \`${n.path}\``);
            if (n.kit)
                lines.push(`  📦 Kit: ${n.kit}`);
            lines.push(`  💡 使用 \`harmonyos_graph_neighbors\` 查看关联节点,nodeId: \`${n.id}\``);
            lines.push('');
        }
        return {
            content: [{ type: 'text', text: lines.join('\n') }],
        };
    });
}
// ============================================================
// harmonyos_graph_neighbors
// ============================================================
const GraphNeighborsSchema = z.object({
    nodeId: z.string()
        .min(1, '节点 ID 不能为空')
        .describe('节点 ID,从 harmonyos_graph_search 结果中获取。如 "module:ohos_app_ability_Ability"'),
    direction: z.enum(['in', 'out', 'both']).default('both')
        .describe('边的方向:in(入边)、out(出边)、both(两者)'),
    relation: z.enum(['belongs_to', 'contains', 'references', 'related'])
        .optional()
        .describe('限定关系类型'),
    maxResults: z.number().int().min(1).max(100).default(30)
        .describe('最大结果数'),
}).strict();
export function registerGraphNeighborsTool(server) {
    server.registerTool('harmonyos_graph_neighbors', {
        title: 'Get Graph Neighbors',
        description: `获取知识图谱中某个节点的邻居节点和关系。

**使用场景:**
- 了解某个 Kit 包含哪些模块和组件
- 查找某个模块属于哪个 Kit
- 发现与某文档交叉引用的其他文档

**方向:**
- out: 从该节点出发的边(如 Kit → 包含的模块)
- in: 指向该节点的边(如 模块 → 所属的 Kit)
- both: 所有相关边`,
        inputSchema: GraphNeighborsSchema,
        annotations: {
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: true,
        },
    }, async (params) => {
        const guard = guardKnowledge();
        if (guard)
            return { content: [{ type: 'text', text: guard }] };
        const result = graphNeighbors(params.nodeId, {
            direction: params.direction,
            relation: params.relation,
            maxResults: params.maxResults,
        });
        if (!result) {
            // 尝试提供联想
            const allIds = getAllNodeIds();
            const lower = params.nodeId.toLowerCase();
            const suggestions = allIds
                .filter(id => id.toLowerCase().includes(lower))
                .slice(0, 5);
            let text = `未找到节点 "${params.nodeId}"。`;
            if (suggestions.length > 0) {
                text += `\n\n你可能想搜索:\n${suggestions.map(s => `- \`${s}\``).join('\n')}`;
            }
            text += '\n\n使用 harmonyos_graph_search 搜索节点。';
            return { content: [{ type: 'text', text }] };
        }
        const lines = [
            `# 节点: ${formatNode(result.node)}`,
            '',
            `${result.edges.length} 个关联:`,
            '',
        ];
        // 分组
        const byRelation = new Map();
        for (const e of result.edges) {
            const key = e.relation;
            if (!byRelation.has(key))
                byRelation.set(key, []);
            byRelation.get(key).push(e);
        }
        for (const [rel, relEdges] of byRelation) {
            lines.push(`## ${RELATION_LABEL[rel] || rel} (${relEdges.length})`);
            for (const e of relEdges.slice(0, 15)) {
                const neighborId = e.from === result.node.id ? e.to : e.from;
                lines.push(`- \`${neighborId}\``);
            }
            if (relEdges.length > 15) {
                lines.push(`- ... 还有 ${relEdges.length - 15} 个`);
            }
            lines.push('');
        }
        return {
            content: [{ type: 'text', text: lines.join('\n') }],
        };
    });
}
// ============================================================
// harmonyos_graph_path
// ============================================================
const GraphPathSchema = z.object({
    from: z.string()
        .describe('起始节点 ID'),
    to: z.string()
        .describe('目标节点 ID'),
    maxDepth: z.number().int().min(2).max(6).default(4)
        .describe('最大搜索深度'),
}).strict();
export function registerGraphPathTool(server) {
    server.registerTool('harmonyos_graph_path', {
        title: 'Find Graph Path',
        description: `在知识图谱中查找两个节点之间的关联路径。

使用 BFS 算法查找从起始节点到目标节点的最短路径。

**使用场景:**
- 理解 API 模块和 Kit 之间的依赖关系
- 发现两个组件之间通过哪些文档关联
- 追踪某个功能的上下游依赖

**返回:** 路径上的节点序列和边序列。`,
        inputSchema: GraphPathSchema,
        annotations: {
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: true,
        },
    }, async (params) => {
        const guard = guardKnowledge();
        if (guard)
            return { content: [{ type: 'text', text: guard }] };
        const result = graphPath(params.from, params.to, params.maxDepth);
        if (!result) {
            return {
                content: [{
                        type: 'text',
                        text: `在深度 ${params.maxDepth} 内未找到从 "${params.from}" 到 "${params.to}" 的路径。\n\n可能原因:\n- 两个节点之间距离太远\n- 节点 ID 不正确\n- 增大 maxDepth 参数重试`,
                    }],
            };
        }
        const lines = [
            `# 图谱路径: "${params.from}" → "${params.to}"`,
            '',
            `路径长度: ${result.nodes.length} 个节点, ${result.edges.length} 条边`,
            '',
            '## 节点序列',
        ];
        for (let i = 0; i < result.nodes.length; i++) {
            const arrow = i < result.nodes.length - 1 ? ' ↓' : '';
            lines.push(`${i + 1}. ${formatNode(result.nodes[i])}${arrow}`);
        }
        lines.push('');
        lines.push('## 边序列');
        for (const e of result.edges) {
            lines.push(`- ${formatEdge(e)}`);
        }
        return {
            content: [{ type: 'text', text: lines.join('\n') }],
        };
    });
}
// ============================================================
// harmonyos_graph_stats
// ============================================================
const GraphStatsSchema = z.object({}).strict();
export function registerGraphStatsTool(server) {
    server.registerTool('harmonyos_graph_stats', {
        title: 'Graph Statistics',
        description: `获取 HarmonyOS 知识图谱的统计信息。

返回节点总数、边总数、各类型分布,以及 Top Kit(按模块和组件数量排序)。

**使用场景:**
- 了解知识图谱的覆盖范围
- 查看哪些 Kit 的文档最丰富
- 快速评估 HarmonyOS 的能力分布`,
        inputSchema: GraphStatsSchema,
        annotations: {
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: true,
        },
    }, async () => {
        const guard = guardKnowledge();
        if (guard)
            return { content: [{ type: 'text', text: guard }] };
        const stats = graphStats();
        const lines = [
            '# 知识图谱统计',
            '',
            `| 指标 | 值 |`,
            `|------|-----|`,
            `| 节点总数 | ${stats.nodeCount.toLocaleString()} |`,
            `| 边总数 | ${stats.edgeCount.toLocaleString()} |`,
            '',
            '## 节点类型分布',
            '',
            '| 类型 | 数量 |',
            '|------|------|',
        ];
        for (const [type, count] of Object.entries(stats.nodeTypes).sort((a, b) => b[1] - a[1])) {
            const emoji = TYPE_EMOJI[type] || '';
            lines.push(`| ${emoji} ${type} | ${count.toLocaleString()} |`);
        }
        lines.push('');
        lines.push('## 边类型分布');
        lines.push('');
        lines.push('| 关系 | 数量 |');
        lines.push('|------|------|');
        for (const [rel, count] of Object.entries(stats.edgeTypes).sort((a, b) => b[1] - a[1])) {
            const label = RELATION_LABEL[rel] || rel;
            lines.push(`| ${label} | ${count.toLocaleString()} |`);
        }
        lines.push('');
        lines.push('## Top Kit(按模块+组件数量)');
        lines.push('');
        for (let i = 0; i < stats.topKits.length; i++) {
            const k = stats.topKits[i];
            lines.push(`${i + 1}. **${k.name}** — ${k.moduleCount} 模块, ${k.componentCount} 组件`);
        }
        return {
            content: [{ type: 'text', text: lines.join('\n') }],
        };
    });
}
//# sourceMappingURL=graph.js.map