/**
 * @deprecated [DC-4] 本应检测死代码的工具自身也是死代码。保留供未来离线治理实现。
 *
 * 机制运行时健康检查。
 *
 * 用于发现“注册了但没有消费”“声明了 lazy import 但没有调用”的长期机制退化。
 * 该模块只做离线治理检查，不参与用户项目运行时路径。
 */
import fs from "node:fs";
import path from "node:path";
const REQUIRED_MECHANISM_ASSETS = {
    "mc-code-maintainability-observability-contract": [
        "templates/internal/rules/代码注释与日志契约规则.md",
        "templates/rules/shared/代码可维护性与可观测性审查.md",
    ],
};
const OFFLINE_GOVERNANCE_MODULES = new Set([
    "mechanism_health_check",
    "config_write_boundary",
    "knowledge_governance_gate",
    "log_governance",
]);
function read(filePath) {
    try {
        return fs.readFileSync(filePath, "utf8");
    }
    catch {
        return "";
    }
}
function findTsFiles(dir) {
    if (!fs.existsSync(dir))
        return [];
    const out = [];
    for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
        const full = path.join(dir, entry.name);
        if (entry.isDirectory())
            out.push(...findTsFiles(full));
        else if (entry.isFile() && entry.name.endsWith(".ts"))
            out.push(full);
    }
    return out;
}
export function detectLazyDeadImports(rootDir) {
    const toolsPath = path.join(rootDir, "src", "adapters", "claude_code", "tools.ts");
    const content = read(toolsPath);
    const findings = [];
    const lazyDecls = [...content.matchAll(/const\s+(lazy[A-Za-z0-9_]+)\s*=\s*createLazy/g)].map((m) => m[1]);
    for (const lazyName of lazyDecls) {
        const usagePattern = new RegExp(`\\b${lazyName}\\s*\\(`, "g");
        const usages = [...content.matchAll(usagePattern)].length;
        if (usages === 0) {
            findings.push({
                severity: "hard_fail",
                kind: "lazy_dead_import",
                target: lazyName,
                message_zh: `${lazyName} 只声明未调用，属于机制死代码风险`,
            });
        }
    }
    return findings;
}
export function detectUnconsumedMechanismIds(rootDir) {
    const findings = [];
    const mcrDir = path.join(rootDir, "src", "engine", "contracts", "mechanism_contract_registry");
    const mcrFiles = fs.existsSync(mcrDir) ? findTsFiles(mcrDir) : [path.join(rootDir, "src", "engine", "contracts", "mechanism_contract_registry.ts")];
    const allText = [
        read(path.join(rootDir, "src", "engine", "contracts", "dual_layer_mechanism_registry.ts")),
        ...mcrFiles.map(read),
        read(path.join(rootDir, "src", "engine", "templates", "asset_manifest.ts")),
        read(path.join(rootDir, "src", "engine", "templates", "consumable_asset_registry.ts")),
    ].join("\n");
    for (const [mechanismId, assets] of Object.entries(REQUIRED_MECHANISM_ASSETS)) {
        if (!allText.includes(mechanismId)) {
            findings.push({
                severity: "hard_fail",
                kind: "unconsumed_mechanism",
                target: mechanismId,
                message_zh: `${mechanismId} 未在机制/资产注册表中形成统一身份`,
            });
        }
        for (const asset of assets) {
            if (!fs.existsSync(path.join(rootDir, asset))) {
                findings.push({
                    severity: "hard_fail",
                    kind: "missing_file",
                    target: asset,
                    message_zh: `机制 ${mechanismId} 声明的资产不存在: ${asset}`,
                });
            }
            if (!allText.includes(asset)) {
                findings.push({
                    severity: "hard_fail",
                    kind: "unconsumed_mechanism",
                    target: `${mechanismId}:${asset}`,
                    message_zh: `机制资产未被注册表消费: ${asset}`,
                });
            }
        }
    }
    return findings;
}
export function scanModuleExports(rootDir) {
    const srcEngine = path.join(rootDir, "src", "engine");
    const toolsText = read(path.join(rootDir, "src", "adapters", "claude_code", "tools.ts"));
    const cliText = read(path.join(rootDir, "src", "bin", "soloforge.ts"));
    const releaseGateText = read(path.join(rootDir, "src", "engine", "release", "release_readiness_gate.ts"));
    const consumerText = `${toolsText}\n${cliText}\n${releaseGateText}`;
    const findings = [];
    for (const file of findTsFiles(srcEngine)) {
        const base = path.basename(file, ".ts");
        if (base.endsWith(".test"))
            continue;
        if (OFFLINE_GOVERNANCE_MODULES.has(base))
            continue;
        const content = read(file);
        if (!/\bexport\s+(function|const|class)\s+/.test(content))
            continue;
        if (!consumerText.includes(`${base}.js`) && !consumerText.includes(base)) {
            findings.push({
                severity: "warning",
                kind: "module_export_unconsumed",
                target: path.relative(rootDir, file),
                message_zh: `引擎模块有导出但未在 CLI/MCP/release gate 文本中发现直接消费点`,
            });
        }
    }
    return findings;
}
export function runFullHealthCheck(rootDir) {
    const findings = [
        ...detectLazyDeadImports(rootDir),
        ...detectUnconsumedMechanismIds(rootDir),
        ...scanModuleExports(rootDir),
    ];
    return {
        checked_at: new Date().toISOString(),
        findings,
        hard_fail_count: findings.filter((f) => f.severity === "hard_fail").length,
        warning_count: findings.filter((f) => f.severity === "warning").length,
    };
}
//# sourceMappingURL=mechanism_health_check.js.map