import fss from "node:fs";
import path from "node:path";
import { resolveProjectConfig } from "../../knowledge/loader.js";
import { debug, userInfo, userError } from "../../engine/core/logger.js";
import { getArgValue, resolveProjectPath, args } from "../args.js";
import { errorMessage } from "../../engine/core/helpers.js";
export async function cmdAuditTemplateMechanisms() {
    debug("CLI", "执行 cmdAuditTemplateMechanisms");
    const asJson = args.includes("--json");
    // 从编译后的二进制位置推导根目录
    const soloforgeRoot = path.resolve(import.meta.dirname, "..", "..");
    const projectPath = fss.existsSync(path.join(soloforgeRoot, "src", "engine"))
        ? soloforgeRoot
        : process.cwd();
    try {
        const { auditTemplateMechanisms } = await import("../../engine/templates/template_mechanism_auditor.js");
        const report = auditTemplateMechanisms(projectPath);
        if (asJson) {
            userInfo(JSON.stringify(report, null, 2));
            if (report.hard_fail_count > 0) {
                process.exit(1);
            }
            return;
        }
        // 人类可读输出
        userInfo(`模板-机制审计报告 (${report.generated_at})`);
        userInfo(`  模板文件: ${report.total_template_files}`);
        userInfo(`  注册资产: ${report.total_registered_assets}`);
        userInfo(`  机制总数: ${report.total_mechanisms}`);
        userInfo("");
        if (report.unmapped_template_assets.length > 0) {
            userInfo(`⚠️  未注册模板 (${report.unmapped_template_assets.length}):`);
            for (const u of report.unmapped_template_assets) {
                userInfo(`  - ${u.path}`);
            }
        }
        if (report.unconsumed_template_assets.length > 0) {
            userInfo(`⚠️  未消费资产 (${report.unconsumed_template_assets.length}):`);
            for (const u of report.unconsumed_template_assets) {
                userInfo(`  - ${u.path} (mode=${u.consumption_mode})`);
            }
        }
        if (report.code_only_mechanisms.length > 0) {
            userInfo(`⚠️  仅代码机制 (无模板层):`);
            for (const m of report.code_only_mechanisms) {
                userInfo(`  - ${m.mechanism_id} (${m.priority}, ${m.status})`);
            }
        }
        if (report.template_only_mechanisms.length > 0) {
            userInfo(`⚠️  仅模板机制 (无代码层):`);
            for (const m of report.template_only_mechanisms) {
                userInfo(`  - ${m.mechanism_id} (${m.priority}, ${m.status})`);
            }
        }
        if (report.required_assets_without_enforcer.length > 0) {
            userInfo(`❌ Required 资产无 enforcer (${report.required_assets_without_enforcer.length}):`);
            for (const r of report.required_assets_without_enforcer) {
                userInfo(`  - ${r.path} (mechanism=${r.owner_mechanism_id})`);
            }
        }
        if (report.overpromised_adapter_rules.length > 0) {
            userInfo(`❌ 适配器过度承诺 (${report.overpromised_adapter_rules.length}):`);
            for (const o of report.overpromised_adapter_rules) {
                userInfo(`  - ${o.source_file}: ${o.promised_mechanism_id} (${o.promise_keywords.join(",")})`);
            }
        }
        if (report.deprecated_assets_injected.length > 0) {
            userInfo(`⚠️  Deprecated 资产仍被注入:`);
            for (const d of report.deprecated_assets_injected) {
                userInfo(`  - ${d.path}`);
            }
        }
        if (report.template_mechanism_drift.length > 0) {
            const driftHard = report.template_mechanism_drift.filter((f) => f.severity === "hard_fail");
            const driftAdvisory = report.template_mechanism_drift.filter((f) => f.severity === "advisory");
            if (driftAdvisory.length > 0) {
                userInfo(`⚠️  漂移 advisory (${driftAdvisory.length}):`);
                for (const f of driftAdvisory) {
                    userInfo(`  - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
                }
            }
            if (driftHard.length > 0) {
                userInfo(`❌ 漂移 hard_fail (${driftHard.length}):`);
                for (const f of driftHard) {
                    userInfo(`  - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
                }
            }
        }
        userInfo("");
        if (report.hard_fail_count > 0) {
            userInfo(`❌ 审计失败: ${report.hard_fail_count} hard_fail, ${report.advisory_count} advisory`);
        }
        else {
            userInfo(`✅ 审计通过: 0 hard_fail, ${report.advisory_count} advisory`);
        }
        // problem-57: 知识资产 schema 审计
        try {
            const { auditKnowledgeAssets, parseAssetFile } = await import("../../engine/knowledge/knowledge_asset_audit.js");
            const knowledgeDirs = [
                path.join(projectPath, "templates", "knowledge", "procedures"),
                path.join(projectPath, "templates", "knowledge", "rules"),
                path.join(projectPath, "templates", "knowledge", "checklists"),
                path.join(projectPath, "templates", "knowledge", "acceptance_templates"),
                path.join(projectPath, "templates", "knowledge", "review_rules"),
                path.join(projectPath, "templates", "knowledge", "workflow_templates"),
            ];
            const assets = [];
            for (const dir of knowledgeDirs) {
                if (!fss.existsSync(dir))
                    continue;
                for (const entry of fss.readdirSync(dir).filter((f) => f.endsWith(".md"))) {
                    const fp = path.join(dir, entry);
                    const content = fss.readFileSync(fp, "utf-8");
                    assets.push(parseAssetFile(fp, content));
                }
            }
            if (assets.length > 0) {
                const kaReport = auditKnowledgeAssets(assets);
                userInfo("");
                userInfo("知识资产审计:");
                userInfo(`  资产数: ${kaReport.total_assets}`);
                userInfo(`  通过: ${kaReport.passed ? "✓" : "✗"}`);
                userInfo(`  hard_fail: ${kaReport.hard_fail_count}, warning: ${kaReport.warning_count}`);
                for (const f of kaReport.findings) {
                    const icon = f.severity === "hard_fail" ? "❌" : "⚠️";
                    userInfo(`    ${icon} ${f.asset_id ?? f.file_path}: ${f.detail} (${f.kind})`);
                }
                if (kaReport.hard_fail_count > 0) {
                    userInfo(`❌ 知识资产审计有 ${kaReport.hard_fail_count} hard_fail`);
                    process.exit(1);
                }
            }
        }
        catch (e) {
            userError(`❌ 知识资产审计异常: ${errorMessage(e)}`);
            process.exit(1);
        }
        if (report.hard_fail_count > 0) {
            process.exit(1);
        }
    }
    catch (e) {
        userError(`❌ audit-template-mechanisms 失败: ${errorMessage(e)}`);
        process.exit(1);
    }
}
export async function cmdAuditDesignArtifacts() {
    debug("CLI", "执行 cmdAuditDesignArtifacts");
    const isJson = args.includes("--json");
    const projectPath = resolveProjectPath();
    const { createDesignArtifactPack, verifyDesignArtifactPack } = await import("../../engine/contracts/design_artifact_pack.js");
    const contract = createDesignArtifactPack("design-artifact-audit-cli");
    const result = verifyDesignArtifactPack(projectPath, contract);
    if (isJson) {
        userInfo(JSON.stringify({ command: "audit-design-artifacts", project_path: projectPath, ...result }, null, 2));
    }
    else {
        userInfo(`设计产物包审计: ${projectPath}`);
        userInfo(`  状态: ${result.status}`);
        userInfo(`  已检查文件: ${result.checked_files.length}`);
        userInfo(`  hard_fail: ${result.findings.filter((finding) => finding.severity === "hard_fail").length}`);
        for (const finding of result.findings) {
            userInfo(`  ${finding.severity === "hard_fail" ? "❌" : "⚠️"} [${finding.code}] ${finding.message_zh}`);
            if (finding.template_path)
                userInfo(`     模板: ${finding.template_path}`);
            if (finding.recovery_command)
                userInfo(`     命令: ${finding.recovery_command}`);
            if (finding.recovery_zh)
                userInfo(`     恢复: ${finding.recovery_zh}`);
        }
        if (result.passed)
            userInfo("✅ 设计产物包复验通过，可作为后续实现输入");
    }
    if (!result.passed)
        process.exit(1);
}
/**
 * 存量设计资产升级只负责安全建立复验基线与归档原文。
 * 修正文档内容仍须经 AI 草案和用户确认后写入，再由 audit 命令真实复验。
 */
export async function cmdUpgradeDesignArtifacts() {
    debug("CLI", "执行 cmdUpgradeDesignArtifacts");
    const apply = args.includes("--apply");
    const confirm = args.includes("--confirm");
    const isJson = args.includes("--json");
    const projectPath = resolveProjectPath();
    const { createDesignArtifactPack, verifyDesignArtifactPack } = await import("../../engine/contracts/design_artifact_pack.js");
    const contract = createDesignArtifactPack("design-artifact-upgrade-cli");
    const audit = verifyDesignArtifactPack(projectPath, contract);
    const presentFiles = audit.checked_files.filter((relativePath) => fss.existsSync(path.join(projectPath, relativePath)));
    const output = {
        command: "upgrade-design-artifacts",
        mode: apply ? "apply" : "dry_run",
        status: audit.passed ? "implementation_ready" : "needs_revalidation",
        present_files: presentFiles,
        findings: audit.findings,
        next_steps: audit.passed
            ? ["设计产物已符合当前标准，无需覆盖现有文件"]
            : ["保留原文归档", "基于 findings 生成修订草案", "用户确认后写入修订文档/OpenAPI/SQL", "重新执行 audit-design-artifacts"],
    };
    if (!apply) {
        if (isJson)
            userInfo(JSON.stringify(output, null, 2));
        else {
            userInfo("设计产物升级计划: dry-run（不会修改现有文档）");
            userInfo(`  当前状态: ${output.status}`);
            userInfo(`  已发现现有资产: ${presentFiles.length}`);
            userInfo(`  待修复项: ${audit.findings.length}`);
            userInfo("  使用 --apply --confirm 仅归档现有基线并登记 needs_revalidation；修订内容仍须用户确认。");
        }
        return;
    }
    if (!confirm) {
        userError("❌ upgrade-design-artifacts --apply 必须同时提供 --confirm，禁止静默改写或归档现有设计文档");
        process.exit(1);
    }
    const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
    const archiveDir = path.join(projectPath, ".soloforge", "design-artifacts", "archive", timestamp);
    fss.mkdirSync(archiveDir, { recursive: true });
    for (const relativePath of presentFiles) {
        const target = path.join(archiveDir, relativePath);
        fss.mkdirSync(path.dirname(target), { recursive: true });
        fss.copyFileSync(path.join(projectPath, relativePath), target);
    }
    const contractDir = path.join(projectPath, ".soloforge", "design-artifacts");
    fss.mkdirSync(contractDir, { recursive: true });
    fss.writeFileSync(path.join(contractDir, "upgrade-contract.json"), JSON.stringify({
        ...contract,
        status: audit.passed ? "implementation_ready" : "needs_revalidation",
        baseline_hashes: audit.hashes,
        findings: audit.findings,
        verified_at: new Date().toISOString(),
        archive_dir: path.relative(projectPath, archiveDir),
        write_policy: "原文仅归档；修订文档须由用户确认后另行写入并重新复验",
    }, null, 2), "utf-8");
    const appliedOutput = { ...output, archive_dir: path.relative(projectPath, archiveDir), original_documents_overwritten: false };
    if (isJson)
        userInfo(JSON.stringify(appliedOutput, null, 2));
    else {
        userInfo(`✅ 已归档现有设计基线: ${appliedOutput.archive_dir}`);
        userInfo("  未覆盖现有设计文档；请确认修订草案后重新执行复验。");
    }
}
export async function cmdValidateKnowledge() {
    debug("CLI", "执行 cmdValidateKnowledge");
    const { validateContractRegistry } = await import("../../engine/contracts/contract_registry.js");
    const { runAllKnowledgeScenarios, extractReadmeCommands } = await import("../../engine/knowledge/knowledge_scenario_registry.js");
    const { listKnowledgeIssueDetailAcceptances, validateKnowledgeIssueDetailAcceptance, } = await import("../../engine/knowledge/knowledge_acceptance_registry.js");
    const isJson = args.includes("--json");
    const cwd = process.cwd();
    const fs = await import("node:fs");
    const pathModule = await import("node:path");
    // 收集项目文件集合
    const existingFiles = new Set();
    function walkDir(dir, prefix) {
        try {
            for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
                const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
                if (entry.isDirectory()) {
                    walkDir(pathModule.join(dir, entry.name), rel);
                }
                else {
                    existingFiles.add(rel);
                }
            }
        }
        catch { /* 忽略不存在目录 */ }
    }
    walkDir(pathModule.join(cwd, "src"), "src");
    walkDir(pathModule.join(cwd, "tests"), "tests");
    // 验证契约注册表
    const contractFindings = validateContractRegistry(existingFiles);
    const hardFails = contractFindings.filter((f) => f.severity === "hard_fail");
    // 读取真实 README 并提取命令
    let readmeCommands;
    try {
        const readmeContent = fs.readFileSync(pathModule.join(cwd, "README.md"), "utf-8");
        readmeCommands = extractReadmeCommands(readmeContent);
    }
    catch { /* README 不存在时跳过 */ }
    // 运行真实场景矩阵
    const scenarioResults = await runAllKnowledgeScenarios(readmeCommands);
    const scenariosPass = scenarioResults.every((s) => s.status === "PASS");
    // 验证 IssueDetailAcceptance 注册表
    const acceptances = listKnowledgeIssueDetailAcceptances();
    const acceptanceFindings = acceptances.flatMap((a) => validateKnowledgeIssueDetailAcceptance(a));
    const acceptanceHardFails = acceptanceFindings.filter((f) => f.severity === "hard_fail");
    const result = {
        contract_hard_fails: hardFails.length,
        issue_acceptances: acceptances.length,
        acceptance_hard_fails: acceptanceHardFails.length,
        scenarios_pass: scenariosPass,
        scenario_results: scenarioResults.map((s) => ({
            scenario_id: s.scenario_id,
            scenario_name: s.scenario_name,
            status: s.status,
            evidence: s.evidence,
            failures: s.failures.length,
        })),
    };
    if (isJson) {
        userInfo(JSON.stringify(result, null, 2));
    }
    else {
        userInfo("═══ 知识模板验证 ═══");
        userInfo(`  契约 hard_fail: ${hardFails.length}`);
        for (const f of hardFails) {
            userInfo(`    ✗ ${f.contract_id}: ${f.message_zh}`);
        }
        userInfo(`  IssueDetailAcceptance: ${acceptances.length} 条, hard_fail: ${acceptanceHardFails.length}`);
        for (const f of acceptanceHardFails) {
            userInfo(`    ✗ ${f.issue_id}: ${f.message_zh}`);
        }
        userInfo(`  场景矩阵:`);
        for (const s of scenarioResults) {
            const icon = s.status === "PASS" ? "✓" : "✗";
            userInfo(`    ${icon} ${s.scenario_id}: ${s.scenario_name} — ${s.status}`);
            for (const ev of s.evidence) {
                userInfo(`      ✓ ${ev}`);
            }
            for (const fl of s.failures) {
                userInfo(`      ✗ ${fl}`);
            }
        }
        const overallPass = hardFails.length === 0 && scenariosPass && acceptanceHardFails.length === 0;
        userInfo(overallPass ? "\n✅ 知识模板验证通过" : "\n❌ 知识模板验证失败");
    }
    const overallPass = hardFails.length === 0 && scenariosPass && acceptanceHardFails.length === 0;
    process.exit(overallPass ? 0 : 1);
}
export async function cmdAuditTemplateVisibility() {
    const projectPath = process.env.SOLOFORGE_PROJECT ?? process.cwd();
    const { auditStandardAssetCoverage } = await import("../../engine/templates/standard_asset_coverage.js");
    const { listBuiltinConsumableAssets } = await import("../../engine/templates/consumable_asset_registry.js");
    const { listTemplateAssetContracts, auditContractCoverage } = await import("../../engine/templates/template_asset_contract_registry.js");
    const { userInfo: ui, userJson: uj } = await import("../../engine/core/logger.js");
    // 使用权威合同注册表作为单一数据源
    const contracts = listTemplateAssetContracts();
    const registeredAssets = listBuiltinConsumableAssets();
    const consumablePaths = new Set(registeredAssets.map((a) => a.path));
    const ownerMap = new Map(contracts.map((c) => [c.path, c.owner_mechanism_id]));
    const consumerMap = new Map(contracts.map((c) => [c.path, [c.mainline_consumer, c.validation_entrypoint].filter(Boolean)]));
    const visibilityMap = new Map(contracts.map((c) => [c.path, c.asset_visibility]));
    // 运行覆盖审计（使用真实合同数据）
    const report = auditStandardAssetCoverage(projectPath, consumablePaths, ownerMap, consumerMap, visibilityMap);
    // 合同覆盖统计
    const coverageReport = auditContractCoverage(projectPath);
    // 可见性统计（从权威合同直接计算）
    const internalCount = contracts.filter((c) => c.asset_visibility === "soloforge_internal" || c.asset_visibility === "scaffold_only").length;
    const userVisibleCount = contracts.filter((c) => c.user_visible).length;
    // 输出报告
    const isJson = args.includes("--json");
    const result = {
        total_assets: report.total_assets,
        registered_contracts: coverageReport.total_contracts,
        contract_covered: coverageReport.contract_covered,
        uncovered_assets: coverageReport.uncovered,
        user_visible_count: userVisibleCount,
        internal_count: internalCount,
        unknown_visibility: coverageReport.visibility_unknown,
        conflict_count: 0,
        missing_bearer: report.missing_standard_bearer,
        missing_revalidation: report.missing_revalidation,
        missing_consumer: report.missing_consumer,
        missing_owner: report.missing_owner,
        unregistered: report.unregistered_assets,
        consumption_evidence_verified: coverageReport.consumption_evidence_verified,
        consumption_evidence_failures: coverageReport.consumption_evidence_failures,
    };
    if (isJson) {
        uj(JSON.stringify(result, null, 2));
    }
    else {
        ui("═══ 模板资产可见性审计报告 ═══");
        ui(`总资产数:       ${report.total_assets}`);
        ui(`注册合同数:     ${coverageReport.total_contracts}（包含非文件运行时资产）`);
        ui(`合同覆盖:       ${coverageReport.contract_covered}`);
        ui(`未覆盖:         ${coverageReport.uncovered}`);
        ui(`用户可见:       ${userVisibleCount}`);
        ui(`内部资产:       ${internalCount}`);
        ui(`未知可见性:     ${coverageReport.visibility_unknown}`);
        ui(`缺标准承载:     ${report.missing_standard_bearer}`);
        ui(`缺复验入口:     ${report.missing_revalidation}`);
        ui(`缺消费者:       ${report.missing_consumer}`);
        ui(`缺 owner:       ${report.missing_owner}`);
        ui(`未注册:         ${report.unregistered_assets}`);
        ui(`消费证据验证:   ${coverageReport.consumption_evidence_verified ? "通过" : "失败"}`);
        for (const failure of coverageReport.consumption_evidence_failures) {
            ui(`  - ${failure}`);
        }
    }
}
export async function cmdAuditProjectKnowledge() {
    const projectPathArg = getArgValue("--project-path");
    const projectPath = projectPathArg ? path.resolve(projectPathArg) : (process.env.SOLOFORGE_PROJECT ?? process.cwd());
    const { auditProjectKnowledge } = await import("../../engine/contracts/project_knowledge_contract.js");
    const { userInfo: ui, userJson: uj } = await import("../../engine/core/logger.js");
    const isJson = args.includes("--json");
    const { config } = await resolveProjectConfig(projectPath, { quiet: isJson });
    const report = auditProjectKnowledge(projectPath, config);
    if (isJson) {
        uj(JSON.stringify(report, null, 2));
        return;
    }
    ui(`用户项目知识审计: ${projectPath}`);
    ui(`  总数: ${report.total}`);
    ui(`  用户自建: ${report.user_authored}`);
    ui(`  内置同步: ${report.builtin_synced}`);
    ui(`  用户修改内置: ${report.user_modified_builtin}`);
    ui(`  冲突: ${report.conflict}`);
    ui(`  hard_rule: ${report.hard_rule}`);
    ui(`  injectable: ${report.injectable}`);
    ui(`  index_only: ${report.index_only}`);
    ui(`  hard_fail: ${report.hard_fail_count}`);
    ui(`  warning: ${report.warning_count}`);
    for (const asset of report.assets) {
        ui(`  - ${asset.rel_path} (${asset.identity}/${asset.consumption})`);
        ui(`    创建: ${asset.evidence.created_by}；索引: ${asset.evidence.indexed_by}`);
        if (asset.lifecycle_stages.length > 0)
            ui(`    阶段: ${asset.lifecycle_stages.join(", ")}`);
        if (asset.path_patterns.length > 0)
            ui(`    路径: ${asset.path_patterns.join(", ")}`);
        if (asset.traceability_ids.length > 0)
            ui(`    追踪: ${asset.traceability_ids.join(", ")}`);
        if (asset.verification_commands.length > 0)
            ui(`    复验: ${asset.verification_commands.join(" / ")}`);
        if (asset.evidence.last_consumed_at) {
            ui(`    最近消费: ${asset.evidence.last_consumption_consumer}/${asset.evidence.last_consumption_action} ${asset.evidence.last_consumed_task} @ ${asset.evidence.last_consumed_at}`);
        }
        for (const finding of asset.findings) {
            const mark = finding.severity === "hard_fail" ? "❌" : finding.severity === "warning" ? "⚠️" : "ℹ️";
            ui(`    ${mark} [${finding.code}] ${finding.message_zh}`);
        }
    }
    if (report.recent_consumption.length > 0) {
        ui("  最近消费证据:");
        for (const item of report.recent_consumption.slice(0, 10)) {
            ui(`    - ${item.rel_path ?? item.asset_id}: ${item.consumer}/${item.action ?? "unknown"} ${item.lifecycle_stage ?? "unknown_stage"} ${item.task_id_or_route} ${item.decision ?? ""}`);
        }
    }
    if (report.recommended_next_steps.length > 0) {
        ui("  下一步:");
        for (const step of report.recommended_next_steps)
            ui(`    - ${step}`);
    }
}
//# sourceMappingURL=audit.js.map