/**
 * 通用决策研讨机制 — 覆盖所有高影响/不确定任务的决策前置确认。
 *
 * 问题六十一要求:
 * - DecisionPackRegistry 支持独立、可组合的决策包
 * - business_process 和 delivery_validation 可独立触发
 * - 同一任务可组合多个 pack
 * - 架构决策六域作为 builtin 子包
 */
import { evaluateArchitectureDecisionWorkshop, } from "./architecture_decision_workshop.js";
// ── 决策包定义 ──
export const DECISION_PACKS = {
    architecture: {
        pack_id: "architecture",
        domains: [], // 架构使用子包六域
        trigger_patterns: [
            /架构设计|总体架构|技术架构|系统设计|architecture\s+design/i,
        ],
        trigger_intent: ["architecture_design"],
        reason: "架构设计任务需要六域决策研讨",
    },
    technology_selection: {
        pack_id: "technology_selection",
        domains: ["technology_selection"],
        trigger_patterns: [
            /技术选型|技术栈选择|技术方案|technology\s+selection|技术决策/i,
        ],
        trigger_intent: [],
        reason: "技术选型需要决策研讨与用户确认",
    },
    data_migration: {
        pack_id: "data_migration",
        domains: ["data_migration"],
        trigger_patterns: [
            /数据迁移|数据库迁移|data\s+migration|schema\s+migration/i,
        ],
        trigger_intent: [],
        reason: "数据迁移需要决策研讨",
    },
    security_policy: {
        pack_id: "security_policy",
        domains: ["security_policy"],
        trigger_patterns: [
            /安全策略|认证授权|权限模型|security\s+policy|auth.*strategy/i,
        ],
        trigger_intent: [],
        reason: "安全策略变更需要决策研讨",
    },
    deployment_infrastructure: {
        pack_id: "deployment_infrastructure",
        domains: ["deployment_infrastructure"],
        trigger_patterns: [
            /部署方案|基础设施|容器化|CI\/CD|deployment|infrastructure/i,
        ],
        trigger_intent: [],
        reason: "部署基础设施变更需要决策研讨",
    },
    product_scope: {
        pack_id: "product_scope",
        domains: ["product_scope"],
        trigger_patterns: [
            /产品范围|需求边界|功能范围|product\s+scope/i,
        ],
        trigger_intent: [],
        reason: "产品范围变更需要决策研讨",
    },
    business_process: {
        pack_id: "business_process",
        domains: ["business_process"],
        trigger_patterns: [
            /业务流程|流程变更|业务规则|business\s+process|流程重构/i,
        ],
        trigger_intent: [],
        reason: "业务流程变更需要决策研讨",
    },
    delivery_validation: {
        pack_id: "delivery_validation",
        domains: ["delivery_validation"],
        trigger_patterns: [
            /交付验证|验收标准|发布策略|delivery\s+validation|release\s+strategy/i,
        ],
        trigger_intent: [],
        reason: "交付验证策略需要决策研讨",
    },
    refactor_migration: {
        pack_id: "refactor_migration",
        domains: ["refactor_migration"],
        trigger_patterns: [
            /重构|迁移方案|refactor|rewrite|migration\s+plan/i,
        ],
        trigger_intent: [],
        reason: "重构/迁移需要决策研讨",
    },
    third_party_integration: {
        pack_id: "third_party_integration",
        domains: ["third_party_integration", "security_policy"],
        trigger_patterns: [
            /第三方集成|外部服务|SDK.*集成|third.?party.*integration/i,
        ],
        trigger_intent: [],
        reason: "第三方集成需要决策研讨",
    },
};
export const EXTENDED_DECISION_DOMAINS = [
    "technology_selection",
    "data_migration",
    "security_policy",
    "deployment_infrastructure",
    "product_scope",
    "business_process",
    "delivery_validation",
    "refactor_migration",
    "third_party_integration",
];
// ── 触发条件 — 返回所有匹配的决策包（可组合） ──
export function matchDecisionPacks(params) {
    const { workflow_intent, intent } = params;
    const intentStr = `${workflow_intent ?? ""} ${intent ?? ""}`;
    const matchedPacks = [];
    const reasons = [];
    for (const [packId, pack] of Object.entries(DECISION_PACKS)) {
        const intentMatch = pack.trigger_patterns.some((p) => p.test(intentStr));
        const workflowMatch = pack.trigger_intent.some((wi) => wi === workflow_intent);
        if (intentMatch || workflowMatch) {
            matchedPacks.push(packId);
            reasons.push(pack.reason);
        }
    }
    return { packs: matchedPacks, reasons };
}
/**
 * 旧接口兼容 — 返回第一个匹配的包类型。
 * 新代码应使用 matchDecisionPacks 获取所有匹配包。
 */
export function requiresDecisionWorkshop(params) {
    const { packs, reasons } = matchDecisionPacks(params);
    if (packs.length === 0) {
        return { required: false, workshop_type: "architecture", reason: "" };
    }
    // 将第一个匹配的 pack 映射为旧 workshop_type
    const packIdToType = {
        architecture: "architecture",
        technology_selection: "technology_selection",
        data_migration: "data_migration",
        security_policy: "security_policy",
        deployment_infrastructure: "deployment",
        product_scope: "product_scope",
        business_process: "multi_domain",
        delivery_validation: "multi_domain",
        refactor_migration: "refactor",
        third_party_integration: "third_party_integration",
    };
    const firstPack = packs[0];
    return {
        required: true,
        workshop_type: packIdToType[firstPack] ?? "multi_domain",
        reason: reasons.join("；"),
    };
}
// ── 创建研讨合同（支持组合包） ──
export function createDecisionWorkshop(taskId, activatedPacks, projectContext = "new_system", triggerReason = "") {
    const packs = Array.isArray(activatedPacks) ? activatedPacks : [activatedPacks];
    const extendedDomains = {};
    // 合并所有激活包的域
    for (const packId of packs) {
        const pack = DECISION_PACKS[packId];
        if (!pack)
            continue;
        for (const domain of pack.domains) {
            if (!extendedDomains[domain]) {
                extendedDomains[domain] = {
                    decision_id: `${taskId}-${domain}`,
                    domain: domain,
                    status: "not_started",
                    required: true,
                    facts_and_constraints: [],
                    evidence_refs: [],
                    options: [],
                };
            }
        }
    }
    return {
        task_id: taskId,
        activated_packs: packs,
        status: "draft",
        project_context: projectContext,
        extended_domains: extendedDomains,
        trigger_reason: triggerReason,
        prerequisite_evidence_refs: [],
        generation_allowed: false,
        blocking_findings: [],
    };
}
function isExtendedDecisionDomain(value) {
    return EXTENDED_DECISION_DOMAINS.includes(value);
}
function isDecisionPackId(value) {
    return Object.prototype.hasOwnProperty.call(DECISION_PACKS, value);
}
function normalizeOption(option) {
    return {
        option_id: String(option?.option_id ?? option?.id ?? option?.label ?? option?.summary ?? "option"),
        summary: String(option?.summary ?? option?.description ?? option?.label ?? ""),
        benefits: Array.isArray(option?.benefits)
            ? option.benefits.map(String)
            : (option?.pros ? [String(option.pros)] : []),
        risks: Array.isArray(option?.risks)
            ? option.risks.map(String)
            : (option?.cons ? [String(option.cons)] : []),
        rejected_reason: option?.rejected_reason ? String(option.rejected_reason) : undefined,
    };
}
function normalizeDecisionRecord(domain, value, taskId) {
    const firstDecision = Array.isArray(value?.decisions) ? value.decisions[0] : undefined;
    const source = firstDecision ?? value ?? {};
    const rawOptions = Array.isArray(source.options) ? source.options : (Array.isArray(value?.options) ? value.options : []);
    const selectedOption = rawOptions.find((option) => option?.selected);
    return {
        decision_id: String(source.decision_id ?? value?.decision_id ?? `${taskId}-${domain}`),
        domain,
        status: (value?.status ?? source.status ?? "not_started"),
        required: typeof value?.required === "boolean" ? value.required : true,
        facts_and_constraints: Array.isArray(value?.facts_and_constraints)
            ? value.facts_and_constraints.map(String)
            : Array.isArray(source.facts_and_constraints)
                ? source.facts_and_constraints.map(String)
                : (source.rationale ? [String(source.rationale)] : []),
        evidence_refs: Array.isArray(value?.evidence_refs)
            ? value.evidence_refs.map(String)
            : Array.isArray(source.evidence_refs)
                ? source.evidence_refs.map(String)
                : [],
        options: rawOptions.map(normalizeOption),
        recommendation: selectedOption
            ? {
                option_id: String(selectedOption.option_id ?? selectedOption.id ?? selectedOption.label ?? "option"),
                rationale: [String(source.rationale ?? source.decision ?? selectedOption.description ?? "用户已选择该方案")],
            }
            : undefined,
        user_confirmation_ref: value?.user_confirmation_ref ? String(value.user_confirmation_ref) : undefined,
        not_applicable_reason: value?.not_applicable_reason ? String(value.not_applicable_reason) : undefined,
        deferred_impact: Array.isArray(value?.deferred_impact) ? value.deferred_impact.map(String) : undefined,
    };
}
/**
 * 兼容 MCP 客户端自然 JSON 回传的研讨结构。
 *
 * AI 常会把 `{ delivery_validation: {...}, status: ... }` 这样的领域字典
 * 当作合同回传。这里把可恢复结构规范化成正式合同；不可恢复结构交给
 * evaluateDecisionWorkshop 返回字段级阻断，避免死锁或 JS 运行时异常。
 */
export function normalizeDecisionWorkshopContract(input, fallbackTaskId = "decision-workshop") {
    if (!input || typeof input !== "object" || Array.isArray(input))
        return undefined;
    const raw = input;
    if (Array.isArray(raw.activated_packs) && raw.extended_domains && typeof raw.extended_domains === "object" && !Array.isArray(raw.extended_domains)) {
        const packs = raw.activated_packs.filter((pack) => typeof pack === "string" && isDecisionPackId(pack));
        const extendedDomains = {};
        for (const [domain, value] of Object.entries(raw.extended_domains)) {
            if (isExtendedDecisionDomain(domain)) {
                extendedDomains[domain] = normalizeDecisionRecord(domain, value, String(raw.task_id ?? fallbackTaskId));
            }
        }
        return {
            task_id: String(raw.task_id ?? fallbackTaskId),
            activated_packs: packs,
            status: (raw.status ?? "draft"),
            project_context: (raw.project_context ?? "new_system"),
            architecture_subpack: raw.architecture_subpack,
            extended_domains: extendedDomains,
            trigger_reason: String(raw.trigger_reason ?? ""),
            prerequisite_evidence_refs: Array.isArray(raw.prerequisite_evidence_refs)
                ? raw.prerequisite_evidence_refs.map(String)
                : [],
            generation_allowed: raw.generation_allowed === true,
            blocking_findings: Array.isArray(raw.blocking_findings) ? raw.blocking_findings.map(String) : [],
        };
    }
    const domainKeys = Object.keys(raw).filter(isExtendedDecisionDomain);
    if (domainKeys.length === 0)
        return undefined;
    const packs = domainKeys.filter(isDecisionPackId);
    const extendedDomains = {};
    const taskId = String(raw.task_id ?? fallbackTaskId);
    for (const domain of domainKeys) {
        extendedDomains[domain] = normalizeDecisionRecord(domain, raw[domain], taskId);
    }
    return {
        task_id: taskId,
        activated_packs: packs.length > 0 ? packs : domainKeys.map((domain) => domain).filter(isDecisionPackId),
        status: (raw.status ?? "draft"),
        project_context: (raw.project_context ?? "new_system"),
        extended_domains: extendedDomains,
        trigger_reason: String(raw.trigger_reason ?? "MCP 客户端回传的领域字典已规范化"),
        prerequisite_evidence_refs: Array.isArray(raw.prerequisite_evidence_refs) ? raw.prerequisite_evidence_refs.map(String) : [],
        generation_allowed: raw.generation_allowed === true,
        blocking_findings: Array.isArray(raw.blocking_findings) ? raw.blocking_findings.map(String) : [],
    };
}
// ── 收集所有必须域 ──
function collectRequiredDomains(packs) {
    const domains = new Set();
    for (const packId of packs) {
        const pack = DECISION_PACKS[packId];
        if (!pack)
            continue;
        for (const d of pack.domains) {
            domains.add(d);
        }
    }
    return [...domains];
}
// ── 评估研讨门禁 ──
export function evaluateDecisionWorkshop(contract) {
    const normalized = normalizeDecisionWorkshopContract(contract);
    if (!normalized) {
        return {
            allowed: false,
            status: "blocked",
            blocking_findings: contract ? ["决策研讨记录结构无效"] : ["缺少决策研讨记录"],
            missing_domains: [],
        };
    }
    contract = normalized;
    if (!Array.isArray(contract.activated_packs) ||
        !contract.extended_domains ||
        typeof contract.extended_domains !== "object" ||
        Array.isArray(contract.extended_domains) ||
        contract.activated_packs.length === 0) {
        return {
            allowed: false,
            status: "blocked",
            blocking_findings: ["决策研讨记录结构无效"],
            missing_domains: [],
        };
    }
    const findings = [];
    const missingDomains = [];
    // 现有系统必须提供前置证据
    if (contract.project_context === "existing_system" && contract.prerequisite_evidence_refs.length === 0) {
        findings.push("现有系统缺少现状分析和差距分析证据");
    }
    // 架构子包检查
    if (contract.activated_packs.includes("architecture")) {
        const archResult = evaluateArchitectureDecisionWorkshop(contract.architecture_subpack);
        if (!archResult.allowed) {
            findings.push(...archResult.blocking_findings);
            missingDomains.push(...archResult.missing_domains);
        }
    }
    // 所有激活包的域检查
    const requiredDomains = collectRequiredDomains(contract.activated_packs);
    for (const domain of requiredDomains) {
        const record = contract.extended_domains[domain];
        if (!record) {
            missingDomains.push(domain);
            findings.push(`缺少决策域记录: ${domain}`);
            continue;
        }
        if (!isTerminalStatus(record.status)) {
            missingDomains.push(domain);
            findings.push(`决策域 ${domain} 尚未确认 (${record.status})`);
        }
        if (record.status === "confirmed" && !record.user_confirmation_ref) {
            missingDomains.push(domain);
            findings.push(`决策域 ${domain} 标记 confirmed 但缺少用户确认引用`);
        }
        if (record.status === "not_applicable_with_reason" && !record.not_applicable_reason) {
            missingDomains.push(domain);
            findings.push(`决策域 ${domain} 标记不适用但缺少理由`);
        }
    }
    return {
        allowed: findings.length === 0,
        status: findings.length === 0 ? "confirmed" : "awaiting_confirmation",
        blocking_findings: findings,
        missing_domains: [...new Set(missingDomains)],
        next_domain: missingDomains[0],
    };
}
function isTerminalStatus(status) {
    return status === "confirmed" ||
        status === "not_applicable_with_reason" ||
        status === "deferred_with_impact";
}
// ── 应用门禁结果 ──
export function applyDecisionWorkshopGate(contract) {
    const normalized = normalizeDecisionWorkshopContract(contract);
    if (!normalized)
        return undefined;
    const gate = evaluateDecisionWorkshop(normalized);
    return {
        ...normalized,
        status: gate.status,
        generation_allowed: gate.allowed,
        blocking_findings: gate.blocking_findings,
    };
}
//# sourceMappingURL=decision_workshop.js.map