/**
 * Knowledge Asset Consumer — 问题五十七消费链路实现。
 *
 * 为 intent_router、expander、verifier、adapter prompt、sync/migration、observability
 * 提供统一的知识资产消费接口。所有组件通过此模块消费 KnowledgeAssetFrontmatter 标准字段。
 */
import fs from "node:fs";
import path from "node:path";
import matter from "gray-matter";
import { getConsumptionTraces, getTraceCounts } from "../templates/consumption_trace_store.js";
// ── 核心函数 ──
/**
 * 加载知识资产注册表 — 使用 gray-matter YAML 解析 templates/** (internal/rules, procedures, rules/shared, checklists, artifacts/shared, domain, internal/patterns, profiles) 和 templates/patterns/**。
 */
export function loadKnowledgeAssetRegistry(baseDir) {
    const assets = [];
    const scanPaths = [
        "templates/internal/rules",
        "templates/procedures",
        "templates/rules/shared",
        "templates/checklists",
        "templates/artifacts/shared",
        "templates/domain",
        "templates/internal/patterns",
        "templates/artifacts/shared",
        "templates/patterns",
    ];
    for (const d of scanPaths) {
        const dp = path.join(baseDir, d);
        if (!fs.existsSync(dp))
            continue;
        const stack = [dp];
        while (stack.length > 0) {
            const current = stack.pop();
            for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
                const fpath = path.join(current, entry.name);
                if (entry.isDirectory()) {
                    stack.push(fpath);
                    continue;
                }
                if (!entry.name.endsWith(".md"))
                    continue;
                try {
                    const raw = fs.readFileSync(fpath, "utf-8");
                    const parsed = matter(raw);
                    const fm = (parsed.data || {});
                    const assetId = fm.id || fm.name || entry.name;
                    assets.push({ asset_id: assetId, frontmatter: fm, file_path: fpath });
                }
                catch {
                    // gray-matter 解析失败 — 跳过，审计时会捕获
                }
            }
        }
    }
    return assets;
}
/**
 * 为 intent_router 消费知识资产字段。
 * 消费: routes, primary_triggers, negative_triggers, specificity
 * 兼容旧格式：when → primary_triggers
 */
export function consumeForRouter(assets) {
    const fields = [];
    const records = [];
    for (const asset of assets) {
        const fm = asset.frontmatter;
        const routes = parseArrayField(fm.routes);
        const primaryTriggers = parseArrayField(fm.primary_triggers || fm.when);
        const negativeTriggers = parseArrayField(fm.negative_triggers);
        const specificity = parseInt(String(fm.specificity || "0"), 10);
        if (routes.length > 0 || primaryTriggers.length > 0) {
            fields.push({
                routes,
                primary_triggers: primaryTriggers,
                negative_triggers: negativeTriggers,
                specificity,
            });
            records.push({
                asset_id: asset.asset_id,
                asset_name: fm.name || asset.asset_id,
                file_path: asset.file_path,
                fields_consumed: ["routes", "primary_triggers", "negative_triggers", "specificity"],
                consumer: "intent_router",
                consumed_at: new Date().toISOString(),
            });
        }
    }
    return { fields, records };
}
/**
 * 为 intent_expander 消费知识资产字段。
 * 消费: authority, priority, required_evidence, asset_kind
 */
export function consumeForExpander(assets) {
    const fields = [];
    const records = [];
    for (const asset of assets) {
        const fm = asset.frontmatter;
        fields.push({
            authority: fm.authority || "supporting",
            priority: fm.priority || "P3",
            required_evidence: parseArrayField(fm.required_evidence),
            asset_kind: fm.asset_kind || fm.type || "domain_knowledge",
        });
        records.push({
            asset_id: asset.asset_id,
            asset_name: fm.name || asset.asset_id,
            file_path: asset.file_path,
            fields_consumed: ["authority", "priority", "required_evidence", "asset_kind"],
            consumer: "intent_expander",
            consumed_at: new Date().toISOString(),
        });
    }
    return { fields, records };
}
/**
 * 为 verifier 消费知识资产字段。
 * 消费: hard_blocks, required_evidence, fallback, lifecycle_status
 */
export function consumeForVerifier(assets) {
    const fields = [];
    const records = [];
    for (const asset of assets) {
        const fm = asset.frontmatter;
        fields.push({
            hard_blocks: parseArrayField(fm.hard_blocks),
            required_evidence: parseArrayField(fm.required_evidence),
            fallback: fm.fallback || "none",
            lifecycle_status: fm.lifecycle_status || "active",
        });
        records.push({
            asset_id: asset.asset_id,
            asset_name: fm.name || asset.asset_id,
            file_path: asset.file_path,
            fields_consumed: ["hard_blocks", "required_evidence", "fallback", "lifecycle_status"],
            consumer: "verifier",
            consumed_at: new Date().toISOString(),
        });
    }
    return { fields, records };
}
/**
 * 为 adapter_prompt 消费知识资产字段。
 * 消费: name, scope, version
 */
export function consumeForAdapterPrompt(assets) {
    const fields = [];
    const records = [];
    for (const asset of assets) {
        const fm = asset.frontmatter;
        fields.push({
            name: fm.name || asset.asset_id,
            scope: parseArrayField(fm.scope),
            version: fm.version || "0.0.0",
        });
        records.push({
            asset_id: asset.asset_id,
            asset_name: fm.name || asset.asset_id,
            file_path: asset.file_path,
            fields_consumed: ["name", "scope", "version"],
            consumer: "adapter_prompt",
            consumed_at: new Date().toISOString(),
        });
    }
    return { fields, records };
}
/**
 * 生成完整的知识消费报告。
 */
export function generateKnowledgeConsumptionReport(baseDir) {
    const assets = loadKnowledgeAssetRegistry(baseDir);
    const routerConsumption = consumeForRouter(assets);
    const expanderConsumption = consumeForExpander(assets);
    const verifierConsumption = consumeForVerifier(assets);
    const adapterConsumption = consumeForAdapterPrompt(assets);
    // ── 真实 trace 证据（来自统一 trace store，非离线扫描）──
    const allTraces = getConsumptionTraces();
    const traceCounts = getTraceCounts();
    const toRecord = (t, consumerName) => ({
        asset_id: t.asset_id,
        asset_name: t.asset_id,
        file_path: "runtime_trace_store",
        fields_consumed: t.fields_consumed,
        consumer: consumerName,
        consumed_at: t.consumed_at,
    });
    const runtimeRouter = allTraces.filter(t => t.consumer === "router").map(t => toRecord(t, "intent_router"));
    const runtimeExpander = allTraces.filter(t => t.consumer === "expander").map(t => toRecord(t, "intent_expander"));
    const runtimeVerifier = allTraces.filter(t => t.consumer === "verifier").map(t => toRecord(t, "verifier"));
    const runtimeAdapter = allTraces.filter(t => t.consumer === "adapter_prompt").map(t => toRecord(t, "adapter_prompt"));
    // P2/P3 资产过滤
    const p0p1Dirs = ["templates/internal/rules", "templates/procedures",
        "templates/rules/shared", "templates/checklists"];
    const isP0P1 = (a) => p0p1Dirs.some(d => a.file_path.startsWith(path.join(baseDir, d)));
    const p0p1Active = assets.filter(a => {
        const status = a.frontmatter.lifecycle_status;
        return status === "active" && isP0P1(a);
    });
    const p2p3Assets = assets.filter(a => !isP0P1(a));
    const deprecatedFiltered = assets.filter(a => {
        const status = a.frontmatter.lifecycle_status;
        return ["deprecated", "draft", "quarantine"].includes(status);
    }).map(a => ({ asset_id: a.asset_id, reason: a.frontmatter.lifecycle_status || "unknown" }));
    const p2p3Filtered = p2p3Assets.map(a => ({ asset_id: a.asset_id, reason: "P2/P3 backlog: 暂不入注入链路" }));
    return {
        generated_at: new Date().toISOString(),
        indexed_catalog: {
            total_assets: assets.length,
            assets: assets.map(a => ({
                asset_id: a.asset_id,
                file_path: a.file_path,
                asset_kind: a.frontmatter.asset_kind || "unknown",
                priority: a.frontmatter.priority || "P3",
            })),
        },
        registry_records: {
            router: routerConsumption.records,
            expander: expanderConsumption.records,
            verifier: verifierConsumption.records,
            adapter_prompt: adapterConsumption.records,
        },
        runtime_consumption_traces: {
            router: runtimeRouter,
            expander: runtimeExpander,
            verifier: runtimeVerifier,
            adapter_prompt: runtimeAdapter,
        },
        consumers: {
            router: runtimeRouter,
            expander: runtimeExpander,
            verifier: runtimeVerifier,
            adapter_prompt: runtimeAdapter,
        },
        snapshot: {
            build_id: `consumption-${Date.now()}`,
            route: "knowledge_asset_consumer",
            indexed_assets: assets.map((a) => a.asset_id),
            injected_assets: p0p1Active.map((a) => a.asset_id),
            filtered_assets: [...deprecatedFiltered, ...p2p3Filtered],
            degraded_assets: [],
            backlog_assets: p2p3Assets.map(a => ({ asset_id: a.asset_id, reason: "P2/P3 backlog" })),
            conflict_resolutions: [],
            generated_at: new Date().toISOString(),
            total_indexed: assets.length,
            total_injected: p0p1Active.length,
            total_filtered: deprecatedFiltered.length + p2p3Filtered.length,
            total_degraded: 0,
            total_backlog: p2p3Assets.length,
        },
        total_assets_indexed: assets.length,
        total_assets_injected: p0p1Active.length,
        real_trace_evidence: {
            router_entries: traceCounts.router,
            verifier_entries: traceCounts.verifier,
            expander_entries: traceCounts.expander,
            adapter_entries: traceCounts.adapter_prompt,
            p0p1_injected: p0p1Active.length,
            p2p3_backlog: p2p3Assets.length,
        },
    };
}
/**
 * 解析字段值为字符串数组（兼容 gray-matter 的真实数组和旧式字符串）。
 */
function parseArrayField(val) {
    if (!val)
        return [];
    if (Array.isArray(val))
        return val.map((v) => String(v).trim());
    if (typeof val === "string") {
        const trimmed = val.trim();
        if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
            const inner = trimmed.slice(1, -1);
            if (inner.trim() === "")
                return [];
            return inner.split(",").map((s) => s.trim().replace(/^"(.*)"$/, "$1").replace(/^'(.*)'$/, "$1"));
        }
        return [trimmed];
    }
    return [String(val)];
}
//# sourceMappingURL=knowledge_asset_consumer.js.map