/**
 * 门禁检查模块 — Phase 16: 工作流导航契约行为验证（问题六十五）。
 */
import path from "node:path";
import fs from "node:fs";
import { errorMessage } from "../../core/helpers.js";
export async function check(ctx, hardFail, info) {
    const rootDir = ctx.rootDir;
    const _info = info ?? (() => { });
    // 1. 编译产物存在性
    const navPath = path.join(rootDir, "dist", "engine", "workflow", "next_action_planner.js");
    if (!fs.existsSync(navPath)) {
        hardFail("NAVIGATION_MODULE_MISSING", "problem-65: next_action_planner.js 未编译到 dist/", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "发布门禁不检查问题-65 导航机制是否存在", "实现 next_action_planner 并编译");
        return;
    }
    // 2. 核心导出存在性
    // eslint-disable-next-line @typescript-eslint/consistent-type-imports -- 动态导入需要 typeof import() 类型声明
    let nav;
    try {
        nav = await import(navPath);
    }
    catch (e) {
        hardFail("NAVIGATION_IMPORT_ERROR", `problem-65: next_action_planner 导入失败: ${errorMessage(e)}`, ["src/engine/workflow/next_action_planner.ts"], "problem-65", "导航模块存在但不可导入", "修复导入错误");
        return;
    }
    if (typeof nav.planNextAction !== "function") {
        hardFail("NAVIGATION_EXPORT_MISSING", "problem-65: next_action_planner 未导出 planNextAction 函数", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "导航模块缺少核心导出", "添加 planNextAction 导出");
    }
    if (typeof nav.computeDisallowedActions !== "function") {
        hardFail("NAVIGATION_DISALLOWED_MISSING", "problem-65: next_action_planner 未导出 computeDisallowedActions 函数", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "禁止动作规则计算函数缺失", "添加 computeDisallowedActions 导出");
    }
    const repairPath = path.join(rootDir, "dist", "engine", "config", "config_auto_repair.js");
    if (!fs.existsSync(repairPath)) {
        hardFail("NAVIGATION_CONFIG_REPAIR_MODULE_MISSING", "problem-65: config_auto_repair.js 未编译到 dist/，机械配置问题无法自动修复", ["src/engine/config/config_auto_repair.ts"], "problem-65", "导航只提示配置待确认，不检查自动修复能力是否存在", "实现 config_auto_repair 并接入导航");
    }
    else {
        try {
            const repairMod = await import(repairPath);
            if (typeof repairMod.analyzeConfigRepair !== "function" || typeof repairMod.repairProjectConfig !== "function") {
                hardFail("NAVIGATION_CONFIG_REPAIR_EXPORT_MISSING", "problem-65: config_auto_repair 必须导出 analyzeConfigRepair 和 repairProjectConfig", ["src/engine/config/config_auto_repair.ts"], "problem-65", "自动修复模块存在但主链路不可消费", "补齐自动修复导出函数");
            }
        }
        catch (e) {
            hardFail("NAVIGATION_CONFIG_REPAIR_IMPORT_ERROR", `problem-65: config_auto_repair 导入失败: ${errorMessage(e)}`, ["src/engine/config/config_auto_repair.ts"], "problem-65", "自动修复模块存在但不可导入", "修复 config_auto_repair 导入错误");
        }
    }
    // 3. 行为验证: 未初始化项目应返回 uninitialized
    const tmpDir = path.join(rootDir, ".soloforge-gate-nav-test-" + Date.now());
    try {
        fs.mkdirSync(tmpDir, { recursive: true });
        const plan = await nav.planNextAction(tmpDir);
        if (plan.project_stage !== "uninitialized") {
            hardFail("NAVIGATION_BEHAVIOR_UNINIT", `problem-65: 未初始化项目的阶段应为 uninitialized，实际为 ${plan.project_stage}`, ["src/engine/workflow/project_stage_detector.ts"], "problem-65", "导航未正确检测未初始化项目", "修复 detectProjectStage 逻辑");
        }
        if (!plan.work_package || plan.work_package.action !== "初始化") {
            hardFail("NAVIGATION_BEHAVIOR_INIT_WP", `problem-65: 未初始化项目的工作包应为 sf_init，实际为 ${plan.work_package?.action ?? "null"}`, ["src/engine/workflow/next_action_planner.ts"], "problem-65", "导航工作包未正确推荐初始化", "修复 computeWorkPackage 逻辑");
        }
        if (!plan.confirmation_decisions) {
            hardFail("NAVIGATION_CONFIRMATION_TIER_MISSING", "problem-65: 导航计划缺少 confirmation_decisions 分级结构", ["src/engine/workflow/next_action_planner.ts", "src/engine/workflow/workflow_navigation_contract.ts"], "problem-65", "旧导航只输出笼统确认提示，用户不知道哪些必须确认", "补充 must_confirm/should_confirm/auto_resolvable 分级");
        }
        else {
            const decisions = plan.confirmation_decisions;
            if (!Array.isArray(decisions.must_confirm) || !Array.isArray(decisions.should_confirm) || !Array.isArray(decisions.auto_resolvable)) {
                hardFail("NAVIGATION_CONFIRMATION_TIER_INVALID", "problem-65: confirmation_decisions 必须同时包含 must_confirm / should_confirm / auto_resolvable 数组", ["src/engine/workflow/workflow_navigation_contract.ts"], "problem-65", "确认项没有结构化分级", "修复 ConfirmationDecisionSummary 类型和 planNextAction 输出");
            }
            if ((decisions.must_confirm?.length ?? 0) !== 0) {
                hardFail("NAVIGATION_GREENFIELD_FALSE_MUST_CONFIRM", "problem-65: 从 0 开发的未初始化项目不得要求确认既有项目事实", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "空项目确认口径错误，把基线确认当成既有事实确认", "将新项目基线归类为 should_confirm，不阻塞初始化和只读规划");
            }
            const greenfieldHint = JSON.stringify(decisions.should_confirm ?? []);
            if (!greenfieldHint.includes("从 0 开发时没有既有项目事实可确认")) {
                hardFail("NAVIGATION_GREENFIELD_CONFIRMATION_EXPLANATION_MISSING", "problem-65: 新项目确认提示必须说明没有既有项目事实，只确认目标、边界、技术选择和默认口径", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "用户不知道空项目如何确认", "补充新项目基线确认说明");
            }
        }
    }
    catch (e) {
        hardFail("NAVIGATION_BEHAVIOR_ERROR", `problem-65: 行为级检查执行失败: ${errorMessage(e)}`, ["src/engine/workflow/next_action_planner.ts"], "problem-65", "导航机制行为检查不可执行", "修复导航机制代码");
    }
    finally {
        try {
            fs.rmSync(tmpDir, { recursive: true });
        }
        catch { }
    }
    // 3.1 行为验证: 机械配置问题必须归类为 auto_resolvable，不得要求用户确认业务口径
    const repairTmpDir = path.join(rootDir, ".soloforge-gate-config-repair-" + Date.now());
    try {
        const sfDir = path.join(repairTmpDir, ".soloforge");
        fs.mkdirSync(sfDir, { recursive: true });
        fs.writeFileSync(path.join(sfDir, "config.yaml"), [
            "schema_version: 1",
            "name: demo-saas",
            "tech_stack:",
            "  backend:",
            "    lang: java",
            "    framework: spring-boot",
            "    version: 3",
            "  frontend:",
            "    lang: typescript",
            "    framework: react",
            "    version: 18",
            "product_profile: saas",
            "repos: []",
            "build_commands:",
            "  backend:",
            "    build: mvn -q -DskipTests package",
            "    test: mvn test",
            "    full: mvn verify",
            "  frontend:",
            "    build: npm run build",
            "    test: npm test",
            "    full: npm run build && npm test",
            "scope:",
            "  backend: demo-saas-backend",
            "  frontend: demo-saas-frontend",
        ].join("\n"), "utf-8");
        fs.writeFileSync(path.join(sfDir, "config.evidence.json"), JSON.stringify({
            schema_version: 2,
            generated_at: "2026-01-01T00:00:00.000Z",
            fields: {
                name: { value: "old-name", confidence: "high", confidence_source: "confirmed", evidence: ["old"] },
            },
            entries: [],
        }, null, 2), "utf-8");
        const repairPlan = await nav.planNextAction(repairTmpDir);
        const decisions = repairPlan.confirmation_decisions;
        const autoItems = decisions?.auto_resolvable ?? [];
        const hasConfigRepair = autoItems.some((item) => item.id === "config-auto-repair" && item.command_hint === "soloforge config repair");
        if (!hasConfigRepair) {
            hardFail("NAVIGATION_CONFIG_REPAIR_NOT_RECOMMENDED", "problem-65: version/scope/evidence 这类机械配置问题必须推荐 soloforge config repair", ["src/engine/workflow/next_action_planner.ts", "src/engine/config/config_auto_repair.ts"], "problem-65", "旧导航把机械配置问题误当成业务确认", "将机械配置问题归入 auto_resolvable");
        }
        if ((decisions?.must_confirm?.length ?? 0) > 0) {
            hardFail("NAVIGATION_CONFIG_REPAIR_FALSE_MUST_CONFIRM", "problem-65: 机械配置问题不得进入 must_confirm，不得要求用户逐字段确认", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "旧导航把可自动修复项伪装成用户确认项", "保持 config repair 为 auto_resolvable");
        }
        const actionText = decisions?.recommended_action ?? "";
        if (!actionText.includes("soloforge config repair")) {
            hardFail("NAVIGATION_CONFIG_REPAIR_ACTION_MISSING", "problem-65: recommended_action 必须明确给出 soloforge config repair", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "用户不知道下一步该运行哪个命令", "在 recommended_action 中输出自动修复命令");
        }
    }
    catch (e) {
        hardFail("NAVIGATION_CONFIG_REPAIR_BEHAVIOR_ERROR", `problem-65: 配置自动修复导航行为检查失败: ${errorMessage(e)}`, ["src/engine/workflow/next_action_planner.ts", "src/engine/config/config_auto_repair.ts"], "problem-65", "配置自动修复行为未纳入发布门禁", "修复配置自动修复导航行为");
    }
    finally {
        try {
            fs.rmSync(repairTmpDir, { recursive: true });
        }
        catch { }
    }
    // 4. 知识文件存在性
    const rulePath = path.join(rootDir, "templates", "internal", "rules", "工作流导航契约规则.md");
    if (!fs.existsSync(rulePath)) {
        hardFail("NAVIGATION_RULE_MISSING", "problem-65: 缺少知识规则文件 工作流导航契约规则.md", ["templates/internal/rules/工作流导航契约规则.md"], "problem-65", "导航知识规则缺失", "创建知识规则文件");
    }
    const procedurePath = path.join(rootDir, "templates", "procedures", "全生命周期工作流导航.md");
    if (!fs.existsSync(procedurePath)) {
        hardFail("NAVIGATION_PROCEDURE_MISSING", "problem-65: 缺少知识流程文件 全生命周期工作流导航.md", ["templates/procedures/全生命周期工作流导航.md"], "problem-65", "导航知识流程缺失", "创建知识流程文件");
    }
    // 5. CLI 命令存在性
    const cliDist = fs.readFileSync(path.join(rootDir, "dist", "bin", "soloforge.js"), "utf-8");
    if (!cliDist.includes('case "next"') && !cliDist.includes("cmdNext")) {
        hardFail("NAVIGATION_CLI_MISSING", "problem-65: CLI 缺少 next 命令入口", ["src/bin/soloforge.ts"], "problem-65", "CLI 无 next 命令", "添加 case 'next' dispatch");
    }
    if (!cliDist.includes('case "stage"') && !cliDist.includes("cmdStage")) {
        hardFail("NAVIGATION_CLI_STAGE_MISSING", "problem-65: CLI 缺少 stage 命令入口", ["src/bin/soloforge.ts"], "problem-65", "CLI 无 stage 命令", "添加 case 'stage' dispatch");
    }
    if (!cliDist.includes('case "repair"') || !cliDist.includes("cmdConfigRepair")) {
        hardFail("NAVIGATION_CONFIG_REPAIR_CLI_MISSING", "problem-65: CLI 缺少 config repair 命令入口", ["src/bin/soloforge.ts", "src/bin/config_commands.ts"], "problem-65", "自动修复能力存在但用户无法通过 CLI 调用", "添加 soloforge config repair");
    }
    _info("  problem-65 工作流导航行为验证完成");
    // ── Step 25: configuration_pending 行为验证 ──
    // 行为验证 3 — 空项目 configuration_pending 不应被硬阻断
    const greenfieldConfigDir = path.join(rootDir, ".soloforge-gate-greenfield-cp-" + Date.now());
    try {
        fs.mkdirSync(path.join(greenfieldConfigDir, ".soloforge"), { recursive: true });
        const greenfieldCpPlan = await nav.planNextAction(greenfieldConfigDir);
        if (greenfieldCpPlan.project_stage !== "configuration_pending") {
            hardFail("NAVIGATION_GREENFIELD_CONFIG_PENDING_STAGE", `problem-65: 有 .soloforge/ 但无 config 的空项目应为 configuration_pending，实际为 ${greenfieldCpPlan.project_stage}`, ["src/engine/workflow/project_stage_detector.ts"], "problem-65", "门禁不检查 configuration_pending 空项目阶段检测", "修复 detectProjectStage 逻辑");
        }
        if ((greenfieldCpPlan.confirmation_decisions?.must_confirm?.length ?? 0) !== 0) {
            hardFail("NAVIGATION_GREENFIELD_CONFIG_PENDING_FALSE_MUST_CONFIRM", "problem-65: 空项目 configuration_pending 不得要求 must_confirm", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "空项目不应被 must_confirm 阻断", "修复 computeConfirmationDecisions 逻辑");
        }
        if (greenfieldCpPlan.disallowed_actions.some((a) => a.rule_id === "unconfirmed_config_no_action")) {
            hardFail("NAVIGATION_GREENFIELD_CONFIG_PENDING_NO_BLOCK", "problem-65: 空项目 configuration_pending 不得产生 unconfirmed_config_no_action 阻断规则", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "空项目不应被配置未确认规则阻断", "修复 computeDisallowedActions 规则2");
        }
    }
    catch (e) {
        hardFail("NAVIGATION_GREENFIELD_CONFIG_PENDING_ERROR", `problem-65: 空项目 configuration_pending 行为检查失败: ${errorMessage(e)}`, ["src/engine/workflow/next_action_planner.ts"], "problem-65", "空项目行为验证不可执行", "修复导航代码");
    }
    finally {
        try {
            fs.rmSync(greenfieldConfigDir, { recursive: true });
        }
        catch { }
    }
    // 行为验证 4 — 老项目 configuration_pending 只阻断高风险动作
    const existingConfigDir = path.join(rootDir, ".soloforge-gate-existing-cp-" + Date.now());
    try {
        fs.mkdirSync(path.join(existingConfigDir, ".soloforge"), { recursive: true });
        fs.writeFileSync(path.join(existingConfigDir, "package.json"), "{}");
        fs.mkdirSync(path.join(existingConfigDir, "src"), { recursive: true });
        const existingCpPlan = await nav.planNextAction(existingConfigDir);
        if (existingCpPlan.project_stage !== "configuration_pending") {
            hardFail("NAVIGATION_EXISTING_CONFIG_PENDING_STAGE", `problem-65: 有 .soloforge/ + 源码但无 config 应为 configuration_pending，实际为 ${existingCpPlan.project_stage}`, ["src/engine/workflow/project_stage_detector.ts"], "problem-65", "老项目 configuration_pending 阶段检测错误", "修复 detectProjectStage");
        }
        // 老项目可以有阻断规则，但只允许阻断编码和联调
        const configBlock = existingCpPlan.disallowed_actions.find((a) => a.rule_id === "unconfirmed_config_no_action");
        if (configBlock) {
            if (configBlock.blocked_actions.includes("需求分析") || configBlock.blocked_actions.includes("架构设计")) {
                hardFail("NAVIGATION_EXISTING_CONFIG_PENDING_OVER_BLOCKING", "problem-65: 老项目 configuration_pending 只能阻断编码和联调，不得阻断需求分析/架构设计", ["src/engine/workflow/next_action_planner.ts"], "problem-65", "配置未确认过度阻断", "修复 computeDisallowedActions 规则2");
            }
        }
    }
    catch (e) {
        hardFail("NAVIGATION_EXISTING_CONFIG_PENDING_ERROR", `problem-65: 老项目 configuration_pending 行为检查失败: ${errorMessage(e)}`, ["src/engine/workflow/next_action_planner.ts"], "problem-65", "老项目行为验证不可执行", "修复导航代码");
    }
    finally {
        try {
            fs.rmSync(existingConfigDir, { recursive: true });
        }
        catch { }
    }
}
//# sourceMappingURL=checkWorkflowNavigation.js.map