/**
 * 标准资产契约 — 为每类标准资产定义机器可读契约字段。
 *
 * 覆盖模板、规则、流程、检查清单、审查规则、patterns、脚手架
 * 和 adapter workflow 的契约 schema、验证和修复闭环。
 */
import fs from "node:fs";
import path from "node:path";
import { getArtifactSchema, findMissingSections, findMissingTables, } from "../contracts/artifact_schema_registry.js";
// ── per-kind 必需字段 ──
const KIND_REQUIRED_FIELDS = {
    acceptance_template: [
        "output_kinds", "required_sections", "required_tables",
        "required_fields", "required_artifacts", "forbidden_gaps",
    ],
    rule: [
        "enforced_rules", "violation_codes", "blocking_conditions", "exception_policy",
    ],
    procedure: [
        "entry_conditions", "steps", "exit_conditions", "repair_reverify_policy",
    ],
    checklist: [
        "check_items", "pass_fail_rules", "evidence_required",
    ],
    review_rule: [
        "applicable_languages", "applicable_frameworks", "applicable_file_patterns",
        "review_findings", "severity_mapping",
    ],
    pattern: [
        "guidance_scope", "evidence_role", "not_project_fact_warning",
    ],
    scaffold: [
        "variables", "required_files", "generated_paths",
        "overwrite_policy", "post_generation_checks",
    ],
    adapter_workflow: [
        "hard_rule_markers", "generated_prompt_sections",
        "manifest_binding", "user_visible_summary",
    ],
};
// ── P0 模板契约定义 ──
export const P0_TEMPLATE_CONTRACTS = [
    {
        contract_version: "1.0",
        asset_id: "tpl-architecture-design",
        asset_kind: "acceptance_template",
        owner_mechanism_id: "mc-standard-asset-contract",
        contract_level: "required",
        applicable_routes: ["架构设计", "artifact_generation"],
        applicable_task_types: ["architecture_design", "system_design"],
        applicable_output_paths: ["docs/architecture/01-架构设计文档.md"],
        applicable_tech_stacks: [],
        trigger_conditions: ["用户要求生成架构设计文档", "sf_expand 识别为架构设计任务"],
        required_inputs: ["决策记录", "架构决策研讨闭合确认"],
        required_outputs: ["架构设计文档", "Mermaid 架构图"],
        failure_severity: "hard_fail",
        verification_strategy: ["section_check", "table_check", "artifact_check", "semantic_check"],
        kind_specific: {
            output_kinds: ["architecture_design"],
            required_sections: ["系统概述", "架构决策", "技术选型", "模块设计"],
            required_tables: ["技术选型对比表", "模块职责表"],
            required_fields: [],
            required_artifacts: ["Mermaid 架构图"],
            forbidden_gaps: ["空章节标题", "缺失 Mermaid 代码块"],
        },
    },
    {
        contract_version: "1.0",
        asset_id: "tpl-database-design",
        asset_kind: "acceptance_template",
        owner_mechanism_id: "mc-standard-asset-contract",
        contract_level: "required",
        applicable_routes: ["架构设计", "artifact_generation"],
        applicable_task_types: ["详细设计"],
        applicable_output_paths: ["docs/architecture/02-数据库设计文档.md"],
        applicable_tech_stacks: [],
        trigger_conditions: ["用户要求生成数据库设计文档"],
        required_inputs: ["数据架构决策", "SQL/migration 权威资产"],
        required_outputs: ["数据库设计文档", "SQL 映射"],
        failure_severity: "hard_fail",
        verification_strategy: ["section_check", "table_check", "field_check", "artifact_check"],
        kind_specific: {
            output_kinds: ["database_design"],
            required_sections: ["数据模型", "实体关系", "表结构"],
            required_tables: ["字段定义表"],
            required_fields: ["字段名", "类型", "约束", "说明"],
            required_artifacts: ["SQL/migration 文件"],
            forbidden_gaps: ["缺少字段表的表定义"],
        },
    },
    {
        contract_version: "1.0",
        asset_id: "tpl-api-spec",
        asset_kind: "acceptance_template",
        owner_mechanism_id: "mc-standard-asset-contract",
        contract_level: "required",
        applicable_routes: ["架构设计", "artifact_generation"],
        applicable_task_types: ["详细设计"],
        applicable_output_paths: ["docs/architecture/03-API接口规格文档.md"],
        applicable_tech_stacks: [],
        trigger_conditions: ["用户要求生成 API 接口规格"],
        required_inputs: ["后端架构决策", "OpenAPI 权威资产"],
        required_outputs: ["API 接口规格文档", "OpenAPI 映射"],
        failure_severity: "hard_fail",
        verification_strategy: ["section_check", "table_check", "field_check", "artifact_check", "semantic_check"],
        kind_specific: {
            output_kinds: ["api_specification", "api_spec", "api_design"],
            required_sections: ["接口概览", "请求响应规范"],
            required_tables: ["请求字段表", "响应字段表"],
            required_fields: ["字段名", "类型", "必填", "来源", "说明", "示例", "校验规则", "错误语义"],
            required_artifacts: ["OpenAPI 文件"],
            forbidden_gaps: ["endpoint 缺请求或响应字段表"],
        },
    },
    {
        contract_version: "1.0",
        asset_id: "tpl-consistency-report",
        asset_kind: "acceptance_template",
        owner_mechanism_id: "mc-standard-asset-contract",
        contract_level: "required",
        applicable_routes: ["架构设计", "artifact_generation", "design_consistency_check"],
        applicable_task_types: ["design_consistency_check"],
        applicable_output_paths: ["docs/architecture/99-设计一致性验收报告.md"],
        applicable_tech_stacks: [],
        trigger_conditions: ["设计产物复验", "跨文档一致性检查"],
        required_inputs: ["架构设计文档", "数据库设计文档", "API 接口规格", "OpenAPI", "SQL/migration"],
        required_outputs: ["一致性验收报告"],
        failure_severity: "hard_fail",
        verification_strategy: ["section_check", "artifact_check", "semantic_check"],
        kind_specific: {
            output_kinds: ["consistency_report"],
            required_sections: ["验证范围", "一致性矩阵", "冲突清单", "验收结论"],
            required_tables: ["跨文档追踪矩阵"],
            required_fields: [],
            required_artifacts: ["设计产物引用列表"],
            forbidden_gaps: ["空验收结论"],
        },
    },
    {
        contract_version: "1.0",
        asset_id: "tpl-prototype-spec",
        asset_kind: "acceptance_template",
        owner_mechanism_id: "mc-standard-asset-contract",
        contract_level: "required",
        applicable_routes: ["requirement_analysis"],
        applicable_task_types: ["prototype_specification", "requirement_extraction"],
        applicable_output_paths: ["docs/prototype-spec.md"],
        applicable_tech_stacks: [],
        trigger_conditions: ["用户从原型/源码包提取需求"],
        required_inputs: ["原型材料", "源码包"],
        required_outputs: ["原型说明文档"],
        failure_severity: "hard_fail",
        verification_strategy: ["section_check", "table_check", "semantic_check"],
        kind_specific: {
            output_kinds: ["prototype_specification"],
            required_sections: ["功能概述", "页面结构", "交互流程"],
            required_tables: ["功能清单"],
            required_fields: [],
            required_artifacts: [],
            forbidden_gaps: ["空功能描述"],
        },
    },
];
// ── 核心函数 ──
export function getStandardAssetContractSchema(kind) {
    return KIND_REQUIRED_FIELDS[kind] ?? [];
}
export function verifyStandardAssetContract(contract) {
    const missing = [];
    const messages = [];
    const schema = KIND_REQUIRED_FIELDS[contract.asset_kind] ?? [];
    for (const field of schema) {
        if (!(field in contract.kind_specific)) {
            missing.push(field);
            messages.push(`缺少契约字段: ${field}`);
        }
    }
    // 基础契约验证
    if (!contract.asset_id) {
        missing.push("asset_id");
        messages.push("缺少 asset_id");
    }
    if (!contract.owner_mechanism_id) {
        missing.push("owner_mechanism_id");
        messages.push("缺少 owner_mechanism_id");
    }
    return {
        passed: missing.length === 0,
        contract,
        missing_fields: missing,
        messages,
    };
}
/**
 * 模板匹配 — 综合输出产物类型、工作流意图、路由决策、文件路径和用户要求，
 * 不只用文件名判断。
 */
export function matchTemplateContract(params) {
    const scored = P0_TEMPLATE_CONTRACTS.map((contract) => {
        let score = 0;
        const kindSpecific = contract.kind_specific;
        // 精确路径匹配 — 最高优先级
        if (params.file_path) {
            for (const p of contract.applicable_output_paths) {
                if (params.file_path.endsWith(p) || p.endsWith(params.file_path)) {
                    score += 100;
                    break;
                }
            }
        }
        // 输出产物类型匹配
        if (params.output_artifact_kind) {
            const outputKinds = kindSpecific.output_kinds ?? [];
            if (outputKinds.includes(params.output_artifact_kind))
                score += 50;
        }
        // 路由决策匹配
        if (params.route_decision) {
            if (contract.applicable_routes.includes(params.route_decision))
                score += 30;
        }
        // 工作流意图匹配
        if (params.workflow_intent) {
            if (contract.applicable_routes.includes(params.workflow_intent))
                score += 20;
        }
        return { contract, score };
    });
    scored.sort((a, b) => b.score - a.score);
    return scored.length > 0 && scored[0].score > 0 ? scored[0].contract : null;
}
/**
 * 验证真实产物文件是否满足契约要求。
 */
export function verifyOutputAgainstContract(contract, content, rootDir) {
    const missing = [];
    const messages = [];
    const kindSpecific = contract.kind_specific;
    const strategies = contract.verification_strategy;
    // 章节检查
    if (strategies.includes("section_check")) {
        const requiredSections = kindSpecific.required_sections ?? [];
        for (const section of requiredSections) {
            // 检查标题存在且不是空标题（只有标题没有后续内容）
            const sectionRegex = new RegExp(`#+\\s*${escapeRegExp(section)}`, "i");
            if (!sectionRegex.test(content)) {
                missing.push(`required_section:${section}`);
                messages.push(`缺少必填章节: ${section}`);
            }
        }
    }
    // 表格检查
    if (strategies.includes("table_check")) {
        const requiredTables = kindSpecific.required_tables ?? [];
        for (const table of requiredTables) {
            // 在表格行中搜索表格名称的关键词
            const keywords = table.replace(/表$/, "").slice(0, 8);
            const tableRegex = new RegExp(`\\|.*${escapeRegExp(keywords)}`, "i");
            // 检查 Markdown 表格存在
            if (!content.includes("|") || !tableRegex.test(content)) {
                missing.push(`required_table:${table}`);
                messages.push(`缺少必填表格: ${table}`);
            }
        }
    }
    // 字段检查（API 字段表）
    if (strategies.includes("field_check")) {
        const requiredFields = kindSpecific.required_fields ?? [];
        if (requiredFields.length > 0) {
            const tableRows = content.match(/\|[^\n]+\|/g) ?? [];
            if (tableRows.length > 1) {
                const headerRow = tableRows[0];
                for (const field of requiredFields) {
                    if (!headerRow.includes(field)) {
                        missing.push(`required_field_column:${field}`);
                        messages.push(`字段表缺少必需列: ${field}`);
                    }
                }
            }
        }
    }
    // 权威资产检查
    if (strategies.includes("artifact_check")) {
        const requiredArtifacts = kindSpecific.required_artifacts ?? [];
        for (const artifact of requiredArtifacts) {
            if (/openapi/i.test(artifact)) {
                const openapiPath = path.join(rootDir, "docs/api/openapi.yaml");
                if (!fs.existsSync(openapiPath)) {
                    missing.push(`required_artifact:openapi`);
                    messages.push("缺少 OpenAPI 权威资产，API Markdown 不得单独作为最终权威");
                }
            }
            if (/sql|migration/i.test(artifact)) {
                const sqlRoots = ["db/migrations", "db/schema"];
                const hasSql = sqlRoots.some((r) => {
                    const abs = path.join(rootDir, r);
                    return fs.existsSync(abs);
                });
                if (!hasSql) {
                    missing.push("required_artifact:sql_migration");
                    messages.push("缺少 SQL/migration 权威资产，数据库 Markdown 不得单独作为物理结构结论");
                }
            }
        }
    }
    // Mermaid 语义检查
    if (strategies.includes("semantic_check")) {
        if (/架构|流程|时序|sequence|architecture/i.test(contract.asset_id)) {
            const mermaidBlocks = content.match(/```mermaid\s*\n([\s\S]*?)```/g) ?? [];
            if (mermaidBlocks.length === 0 && /架构|architecture/i.test(contract.asset_id)) {
                missing.push("mermaid_missing");
                messages.push("架构设计文档缺少 Mermaid 图");
            }
            for (const block of mermaidBlocks) {
                const inner = block.replace(/```mermaid\s*\n?/, "").replace(/```$/, "");
                // fence 语法检查
                if (!inner.trim()) {
                    missing.push("mermaid_empty");
                    messages.push("Mermaid 代码块为空");
                }
                // 图类型检查
                const validTypes = ["sequenceDiagram", "flowchart", "graph", "classDiagram", "erDiagram"];
                const hasValidType = validTypes.some((t) => inner.includes(t));
                if (!hasValidType) {
                    missing.push("mermaid_invalid_type");
                    messages.push("Mermaid 代码块缺少有效图类型（sequenceDiagram/flowchart/graph/classDiagram/erDiagram）");
                }
            }
        }
    }
    return {
        passed: missing.length === 0,
        contract,
        missing_fields: missing,
        messages,
    };
}
/**
 * 生成修复重验指令。
 */
export function createRepairReverifyDirective(contract, result) {
    const suggestion = result.messages.length > 0
        ? `请修复以下契约缺口后重新验证: ${result.messages.join("; ")}`
        : "请补充缺失内容后重新验证";
    return {
        phase_directive: "回退",
        asset_id: contract.asset_id,
        contract_id: contract.asset_id,
        missing_fields: result.missing_fields,
        messages: result.messages,
        repair_suggestion: suggestion,
    };
}
/**
 * 检查是否为低风险任务（不应触发模板契约）。
 */
export function isLowRiskTask(params) {
    const designPatterns = [
        /docs\/architecture/i, /docs\/api\/openapi/i,
        /db\/(?:migrations|schema)/i, /架构设计/i, /数据库设计/i, /API接口规格/i,
    ];
    const designRoutes = ["architecture_design", "artifact_generation", "design_consistency_check"];
    if (params.route_decision && designRoutes.includes(params.route_decision))
        return false;
    if (params.workflow_intent && designRoutes.includes(params.workflow_intent))
        return false;
    if (params.changed_files?.some((f) => designPatterns.some((p) => p.test(f))))
        return false;
    return true;
}
/**
 * 检查草稿标记 — 草稿文档不应进入编码消费。
 */
export function isDraftDocument(content) {
    const draftMarkers = ["draft", "not_for_implementation", "needs_template_verification", "草稿", "仅供参考"];
    const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
    if (frontmatterMatch) {
        const frontmatter = frontmatterMatch[1].toLowerCase();
        if (draftMarkers.some((m) => frontmatter.includes(m)))
            return true;
    }
    // 正文开头标记
    const firstLine = content.replace(/^---\n[\s\S]*?\n---\n*/, "").trim().slice(0, 200).toLowerCase();
    return draftMarkers.some((m) => firstLine.includes(m));
}
function escapeRegExp(str) {
    return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// ── 基于 ArtifactSchema Registry 的验证 ──
/**
 * 基于 Schema Registry 的产物验证。
 *
 * 与 verifyOutputAgainstContract() 不同，此函数直接使用
 * artifact_schema_registry 中的 Schema 定义，覆盖全部 19 种产物类型。
 *
 * @param kind 产物类型
 * @param content 文件内容
 * @param rootDir 项目根目录（用于检查附属产物文件）
 * @returns 验证结果
 */
export function verifyOutputAgainstSchema(kind, content, rootDir) {
    const schema = getArtifactSchema(kind);
    if (!schema) {
        return {
            passed: true,
            contract: P0_TEMPLATE_CONTRACTS[0],
            missing_fields: [],
            messages: [`未知产物类型: ${kind}，跳过 Schema 验证`],
        };
    }
    const missing = [];
    const messages = [];
    // 章节检查（使用 registry 的灵活匹配）
    const missingSections = findMissingSections(content, schema);
    for (const section of missingSections) {
        missing.push(`required_section:${section}`);
        messages.push(`缺少必填章节: ${section}`);
    }
    // 表格检查
    const missingTables = findMissingTables(content, schema);
    for (const table of missingTables) {
        missing.push(`required_table:${table}`);
        messages.push(`缺少必填表格: ${table}`);
    }
    // 字段列检查（查找每个表格对应的 header row）
    if (schema.required_fields) {
        const tableRows = content.match(/\|[^\n]+\|/g) ?? [];
        for (const [tableName, fields] of Object.entries(schema.required_fields)) {
            // 查找包含表格关键词的行，作为该表格的 header row
            const tableKeyword = tableName.replace(/表$/, "").slice(0, 8);
            const headerRow = tableRows.find((row) => new RegExp(escapeRegExp(tableKeyword), "i").test(row));
            if (headerRow) {
                for (const field of fields) {
                    if (!headerRow.includes(field)) {
                        missing.push(`required_field_column:${tableName}:${field}`);
                        messages.push(`表格 ${tableName} 缺少必需列: ${field}`);
                    }
                }
            }
        }
    }
    // 附属产物检查
    if (schema.required_artifacts && schema.required_artifacts.length > 0) {
        for (const artifact of schema.required_artifacts) {
            if (/openapi/i.test(artifact)) {
                const openapiPath = path.join(rootDir, "docs/api/openapi.yaml");
                if (!fs.existsSync(openapiPath)) {
                    missing.push("required_artifact:openapi");
                    messages.push("缺少 OpenAPI 权威资产");
                }
            }
            if (/sql|migration/i.test(artifact)) {
                const sqlRoots = ["db/migrations", "db/schema"];
                const hasSql = sqlRoots.some((r) => fs.existsSync(path.join(rootDir, r)));
                if (!hasSql) {
                    missing.push("required_artifact:sql_migration");
                    messages.push("缺少 SQL/migration 权威资产");
                }
            }
            if (/mermaid/i.test(artifact)) {
                const mermaidBlocks = content.match(/```mermaid\s*\n([\s\S]*?)```/g) ?? [];
                if (mermaidBlocks.length === 0) {
                    missing.push("required_artifact:mermaid");
                    messages.push("缺少 Mermaid 架构图");
                }
            }
        }
    }
    // 禁止空白检查
    if (schema.forbidden_gaps && schema.forbidden_gaps.length > 0) {
        for (const gap of schema.forbidden_gaps) {
            if (content.includes(gap)) {
                missing.push(`forbidden_gap:${gap}`);
                messages.push(`发现禁止的空白标记: ${gap}`);
            }
        }
    }
    // 使用第一个 P0 契约作为兼容性 contract 引用
    const fallbackContract = P0_TEMPLATE_CONTRACTS[0];
    return {
        passed: missing.length === 0,
        contract: fallbackContract,
        missing_fields: missing,
        messages,
    };
}
/**
 * 通过产物类型查找对应的 Schema。
 * 用于 matchTemplateContract 的补充查询。
 */
export function findSchemaByArtifactKind(kind) {
    return getArtifactSchema(kind);
}
/**
 * 增强版模板匹配 — 先查 P0 契约，再查 Schema Registry。
 *
 * 优先返回 P0 契约（向后兼容），无匹配时回退到 Registry 查找。
 */
export function matchTemplateContractEnhanced(params) {
    // 先尝试原有 P0 契约匹配
    const p0Result = matchTemplateContract(params);
    if (p0Result)
        return p0Result;
    // 无 P0 匹配时，尝试通过 Schema Registry 查找对应模板
    if (params.output_artifact_kind) {
        const schema = getArtifactSchema(params.output_artifact_kind);
        if (schema?.template_file) {
            // 基于 Schema 构造一个兼容的 StandardAssetContract
            const contract = {
                contract_version: "2.0",
                asset_id: `tpl-schema-${schema.kind}`,
                asset_kind: "acceptance_template",
                owner_mechanism_id: "mc-artifact-schema-registry",
                contract_level: "required",
                applicable_routes: params.route_decision ? [params.route_decision] : [],
                applicable_task_types: [schema.kind],
                applicable_output_paths: [],
                applicable_tech_stacks: [],
                trigger_conditions: [],
                required_inputs: [],
                required_outputs: [schema.template_file],
                failure_severity: "hard_fail",
                verification_strategy: ["section_check", "table_check"],
                kind_specific: {
                    output_kinds: [schema.kind],
                    required_sections: schema.required_sections,
                    required_tables: schema.required_tables,
                    required_fields: schema.required_fields
                        ? Object.values(schema.required_fields).flat()
                        : [],
                    required_artifacts: schema.required_artifacts ?? [],
                    forbidden_gaps: schema.forbidden_gaps ?? [],
                },
            };
            return contract;
        }
    }
    return null;
}
//# sourceMappingURL=standard_asset_contract.js.map