"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.inspectPhaseMilestoneAuthoringReadiness = inspectPhaseMilestoneAuthoringReadiness;
exports.inspectPhaseContractImpactCoverage = inspectPhaseContractImpactCoverage;
exports.createPhaseContractImpactFinding = createPhaseContractImpactFinding;
exports.uniqueSorted = uniqueSorted;
const node_fs_1 = __importDefault(require("node:fs"));
const errors_1 = require("../../errors");
const output_1 = require("../../output");
const authoring_policy_1 = require("../authoring-policy");
const scaffold_application_1 = require("../scaffold-application");
const task_contract_impact_1 = require("../task-contract-impact");
const validation_input_coverage_1 = require("../validation-input-coverage");
const scaffold_target_path_policy_1 = require("../scaffold-target-path-policy");
const authored_scaffold_1 = require("./authored-scaffold");
const phase_parsing_1 = require("./phase-parsing");
const projection_1 = require("./projection");
const task_evidence_1 = require("./task-evidence");
function inspectPhaseMilestoneAuthoringReadiness(repositoryRoot, options) {
    const runtimeEvidencePathPolicy = (0, scaffold_target_path_policy_1.readPlanningScaffoldTargetPathPolicy)(repositoryRoot);
    const phaseOverviewPath = (0, phase_parsing_1.resolvePhaseOverviewPath)(repositoryRoot, options.phaseOverviewPath);
    if (!node_fs_1.default.existsSync(phaseOverviewPath.absolute)) {
        throw (0, errors_1.createUsageError)(`Parent phase overview not found at '${phaseOverviewPath.relative}'.`, ["Run day-shift phase new first or pass the correct --phase-overview path."]);
    }
    const phaseOverviewText = node_fs_1.default.readFileSync(phaseOverviewPath.absolute, "utf8");
    const declaredMilestoneSlugs = (0, authoring_policy_1.declaredPlanningChildSlugs)(phaseOverviewText, "Milestones");
    const childInspection = (0, authoring_policy_1.inspectPlanningChildScaffolds)({
        parentPath: phaseOverviewPath.relative,
        markdownText: phaseOverviewText,
        childKind: "milestone",
        declaredChildSlugs: declaredMilestoneSlugs,
        runtimeEvidencePathPolicy
    });
    const findings = [...childInspection.findings];
    const decompositionIssues = (0, authoring_policy_1.auditParentDecomposition)({
        artifactPath: phaseOverviewPath.relative,
        markdownText: phaseOverviewText,
        childKind: "milestone",
        declaredChildSlugs: declaredMilestoneSlugs
    });
    findings.push(...decompositionIssues.map((issue) => (0, task_evidence_1.createPhaseAuthoringFinding)(issue.code, issue.reason, phaseOverviewPath.relative)));
    if (declaredMilestoneSlugs.length === 0) {
        findings.push((0, task_evidence_1.createPhaseAuthoringFinding)("PLANNING_PHASE_MILESTONE_DECLARATIONS_MISSING", "Phase authoring readiness requires at least one declared milestone.", phaseOverviewPath.relative));
    }
    let parsedPhaseOverview = null;
    try {
        parsedPhaseOverview = (0, phase_parsing_1.parsePhaseOverview)(phaseOverviewPath.absolute, phaseOverviewText);
    }
    catch (error) {
        findings.push(...(0, task_evidence_1.phaseAuthoringErrorFindings)(error, phaseOverviewPath.relative, "PLANNING_PHASE_AUTHORING_CONTRACT_INVALID"));
    }
    const normalizedScaffoldEvidence = [];
    const materializedScaffoldPaths = [];
    const materializedScaffoldRevisions = [];
    const scaffoldProjectionDrift = [];
    if (parsedPhaseOverview !== null) {
        for (const milestoneSlug of declaredMilestoneSlugs) {
            const scaffoldEvidence = childInspection.evidence.find((entry) => entry.childSlug === milestoneSlug);
            if (scaffoldEvidence === undefined || !scaffoldEvidence.complete)
                continue;
            try {
                const authored = (0, authored_scaffold_1.inspectAuthoredMilestoneScaffold)({
                    parentPath: phaseOverviewPath.relative,
                    phaseMarkdownText: phaseOverviewText,
                    milestoneSlug,
                    declaredMilestoneSlugs,
                    milestoneDescription: parsedPhaseOverview.milestoneDescriptions.get(milestoneSlug) ?? "",
                    phaseAcceptanceCriteria: parsedPhaseOverview.acceptanceCriteria,
                    authoritativeCriterionIds: parsedPhaseOverview.runtimeAcceptance?.required === true
                        ? parsedPhaseOverview.runtimeAcceptance.criterionIds
                        : [],
                    scaffoldEvidence,
                    runtimeEvidencePathPolicy,
                    allowIncompleteProjectedTaskEvidence: true
                });
                const normalizedMilestoneEvidence = {
                    milestoneSlug,
                    scaffoldEvidence,
                    criterionIds: [...authored.criterionIds],
                    taskIdentities: authored.tasks.map((task) => {
                        const ownership = task.ownership.length > 0
                            ? task.ownership
                            : scaffoldEvidence.ownership;
                        const dependencies = task.dependencies.length > 0
                            ? task.dependencies
                            : scaffoldEvidence.dependencies;
                        const targetPaths = task.targetPaths.length > 0
                            ? task.targetPaths
                            : scaffoldEvidence.targetPaths;
                        const explicitAdapterPaths = task.adapterPaths.length > 0
                            ? task.adapterPaths
                            : scaffoldEvidence.adapterPaths;
                        const validationCommands = task.validationCommands.length > 0
                            ? task.validationCommands
                            : scaffoldEvidence.validationCommands;
                        const rollback = task.rollback.length > 0
                            ? task.rollback
                            : scaffoldEvidence.rollback;
                        const projectedEvidence = (0, authoring_policy_1.inspectProjectedTaskScaffoldEvidence)({
                            prose: [
                                task.description,
                                ...task.acceptanceCriteria,
                                task.currentBehavior ?? "",
                                task.desiredBehavior,
                                ...ownership
                            ],
                            ownership,
                            dependencies,
                            targetPaths,
                            explicitAdapterPaths,
                            validationCommands,
                            rollback
                        });
                        return {
                            taskSlug: task.slug,
                            description: task.description,
                            criterionIds: [...task.criterionIds],
                            sharedCriterionIds: [...task.sharedCriterionIds],
                            currentBehavior: task.currentBehavior,
                            desiredBehavior: task.desiredBehavior,
                            ownership: [...ownership],
                            dependencies: [...dependencies],
                            targetPaths: [...targetPaths],
                            adapterPaths: [...projectedEvidence.adapterPaths],
                            requiredAdapter: projectedEvidence.requiredAdapter,
                            adapterRequirementReasons: [
                                ...projectedEvidence.adapterRequirementReasons
                            ],
                            validationCommands: [...validationCommands],
                            rollback: [...rollback],
                            missingEvidence: [...projectedEvidence.missingEvidence],
                            complete: projectedEvidence.complete
                        };
                    })
                };
                normalizedScaffoldEvidence.push(normalizedMilestoneEvidence);
                (0, projection_1.inspectMaterializedPhaseScaffoldProjection)({
                    repositoryRoot,
                    phaseOverviewPath: phaseOverviewPath.relative,
                    parsedPhaseOverview,
                    milestoneDescription: parsedPhaseOverview.milestoneDescriptions.get(milestoneSlug) ?? "",
                    milestoneEvidence: normalizedMilestoneEvidence,
                    authoredMilestoneScaffold: authored,
                    materializedScaffoldPaths,
                    materializedScaffoldRevisions,
                    scaffoldProjectionDrift,
                    findings
                });
            }
            catch (error) {
                findings.push(...(0, task_evidence_1.phaseAuthoringErrorFindings)(error, phaseOverviewPath.relative, "PLANNING_MILESTONE_SCAFFOLD_NOT_READY"));
            }
        }
    }
    for (const milestone of normalizedScaffoldEvidence) {
        for (const task of milestone.taskIdentities) {
            findings.push(...task.missingEvidence.map((kind) => (0, output_1.createBlockingValidationFinding)({
                code: `PLANNING_SCAFFOLD_${kind.toUpperCase()}_EVIDENCE_MISSING`,
                message: `Task '${task.taskSlug}' is missing ${kind} evidence required for an executable scaffold.`,
                path: phaseOverviewPath.relative,
                blockingReason: "invalid-command-input",
                recovery: "Complete the nested task's projected scaffold evidence before creating milestone artifacts.",
                evidence: {
                    category: "planning-review",
                    details: {
                        childKind: "task",
                        milestoneSlug: milestone.milestoneSlug,
                        childSlug: task.taskSlug,
                        missingEvidenceKind: kind,
                        requiredAdapter: task.requiredAdapter,
                        adapterRequirementReasons: task.adapterRequirementReasons,
                        requiresRefinement: true,
                        noWriteRequired: true
                    }
                }
            })));
        }
        findings.push(...(0, authoring_policy_1.inspectOrderedTaskScaffoldDependencies)({
            repositoryRoot,
            tasks: milestone.taskIdentities
        }).map((issue) => (0, output_1.createBlockingValidationFinding)({
            code: issue.code,
            message: issue.message,
            path: phaseOverviewPath.relative,
            blockingReason: "invalid-command-input",
            recovery: "Make the dependency exist before this milestone, move its producer to an earlier sibling, or correct the authored dependency path.",
            evidence: {
                category: "planning-review",
                details: {
                    childKind: "task",
                    milestoneSlug: milestone.milestoneSlug,
                    childSlug: issue.consumerTask,
                    consumerTask: issue.consumerTask,
                    dependencyPath: issue.dependencyPath,
                    producerTask: issue.producerTasks.length === 1
                        ? issue.producerTasks[0]
                        : null,
                    producerTasks: issue.producerTasks,
                    consumerSequence: issue.consumerSequence,
                    producerSequence: issue.producerSequences.length === 1
                        ? issue.producerSequences[0]
                        : null,
                    producerSequences: issue.producerSequences,
                    requiresRefinement: true,
                    noWriteRequired: true
                }
            }
        })));
    }
    const contractImpact = inspectPhaseContractImpactCoverage({
        repositoryRoot,
        phaseOverviewPath: phaseOverviewPath.relative,
        normalizedScaffoldEvidence
    });
    findings.push(...contractImpact.findings);
    const uniqueFindings = (0, task_evidence_1.deduplicatePhaseAuthoringFindings)(findings);
    return {
        phaseOverviewPath: phaseOverviewPath.relative,
        phaseRevision: `sha256:${(0, scaffold_application_1.planningScaffoldContentRevision)(phaseOverviewText)}`,
        declaredMilestoneSlugs,
        normalizedScaffoldEvidence,
        contractImpactCoverage: contractImpact.coverage,
        materializedScaffoldPaths,
        materializedScaffoldRevisions,
        scaffoldProjectionDrift,
        findings: uniqueFindings,
        complete: childInspection.complete
            && normalizedScaffoldEvidence.length === declaredMilestoneSlugs.length
            && contractImpact.coverage.requiredComplete
            && uniqueFindings.length === 0
    };
}
function inspectPhaseContractImpactCoverage(options) {
    const baseInspection = (0, task_contract_impact_1.inspectTaskContractImpact)({
        repositoryRoot: options.repositoryRoot,
        targetPaths: [],
        validationCommandsText: ""
    });
    const tasks = options.normalizedScaffoldEvidence.flatMap((milestone) => milestone.taskIdentities.map((task) => {
        const targetPaths = uniqueSorted([
            ...task.targetPaths,
            ...task.adapterPaths
        ]);
        const inspection = (0, task_contract_impact_1.inspectTaskContractImpact)({
            repositoryRoot: options.repositoryRoot,
            targetPaths,
            validationCommandsText: task.validationCommands.join("\n")
        });
        const validationInputCoverage = (0, validation_input_coverage_1.inspectDeclaredValidationInputCoverage)({
            repositoryRoot: options.repositoryRoot,
            declaredCommands: task.validationCommands,
            writableTargets: targetPaths,
            generatedOutputs: inspection.generatedOutputs.flatMap((entry) => entry.path === null ? [] : [entry.path]),
            dependencies: [
                ...task.dependencies,
                ...inspection.readOnlyDependencies.flatMap((entry) => entry.path === null ? [] : [entry.path]),
                ...inspection.frozenDependencies.flatMap((entry) => entry.path === null ? [] : [entry.path])
            ]
        });
        return {
            inspection,
            validationInputCoverage,
            coverage: {
                milestoneSlug: milestone.milestoneSlug,
                taskSlug: task.taskSlug,
                targetPaths,
                contractState: inspection.contractState,
                unknownPolicy: inspection.unknownPolicy,
                fingerprint: inspection.fingerprint,
                unknownPaths: inspection.contractState === "valid"
                    ? [...inspection.unknown]
                    : [],
                blockingIssues: [...inspection.blockingIssues],
                requiredComplete: inspection.requiredComplete
            }
        };
    }));
    const uniqueTargets = uniqueSorted(tasks.flatMap((entry) => entry.coverage.targetPaths));
    const unknownPaths = baseInspection.contractState === "valid"
        ? uniqueSorted(tasks.flatMap((entry) => entry.coverage.unknownPaths))
        : [];
    const findings = [];
    if (baseInspection.contractState === "invalid") {
        findings.push(createPhaseContractImpactFinding({
            code: "PHASE_CONTRACT_IMPACT_CONTRACT_INVALID",
            message: baseInspection.blockingIssues.join(" "),
            affectedPaths: [task_contract_impact_1.TASK_CONTRACT_IMPACT_PATH],
            details: {
                contractState: baseInspection.contractState
            }
        }));
    }
    if (baseInspection.contractState === "valid") {
        for (const milestone of options.normalizedScaffoldEvidence) {
            const milestoneTasks = tasks.filter((entry) => entry.coverage.milestoneSlug === milestone.milestoneSlug);
            const milestoneUnknownPaths = uniqueSorted(milestoneTasks.flatMap((entry) => entry.coverage.unknownPaths));
            if (milestoneUnknownPaths.length > 0
                && baseInspection.unknownPolicy === "blocking") {
                findings.push(createPhaseContractImpactFinding({
                    code: "PHASE_CONTRACT_IMPACT_COVERAGE_REQUIRED",
                    message: `Milestone '${milestone.milestoneSlug}' declares ${milestoneUnknownPaths.length} target path(s) without exact producer relationships in ${task_contract_impact_1.TASK_CONTRACT_IMPACT_PATH}; phase authoring cannot authorize ordinary strict task execution.`,
                    affectedPaths: milestoneUnknownPaths,
                    details: {
                        milestoneSlug: milestone.milestoneSlug,
                        taskSlugs: milestoneTasks.map((entry) => entry.coverage.taskSlug),
                        unknownPolicy: baseInspection.unknownPolicy,
                        unknownPaths: milestoneUnknownPaths
                    }
                }));
            }
        }
        for (const task of tasks) {
            for (const finding of task.inspection.findings) {
                if (finding.severity !== "error"
                    || finding.code === "TASK_CONTRACT_IMPACT_UNKNOWN_BLOCKED"
                    || finding.code === "TASK_CONTRACT_IMPACT_CONTRACT_INVALID")
                    continue;
                findings.push(createPhaseContractImpactFinding({
                    code: finding.code.replace(/^TASK_/u, "PHASE_"),
                    message: `Milestone '${task.coverage.milestoneSlug}' task '${task.coverage.taskSlug}': ${finding.message}`,
                    affectedPaths: finding.affectedPaths?.map((entry) => entry.path)
                        ?? [finding.path ?? task_contract_impact_1.TASK_CONTRACT_IMPACT_PATH],
                    details: {
                        milestoneSlug: task.coverage.milestoneSlug,
                        taskSlug: task.coverage.taskSlug,
                        sourceFindingCode: finding.code,
                        contractImpactFingerprint: task.coverage.fingerprint
                    }
                }));
            }
        }
    }
    for (const task of tasks) {
        findings.push(...task.validationInputCoverage.issues.map((issue) => (0, validation_input_coverage_1.createValidationInputCoverageFinding)({
            issue: {
                ...issue,
                message: `Milestone '${task.coverage.milestoneSlug}' task '${task.coverage.taskSlug}': ${issue.message}`
            },
            codePrefix: "PHASE",
            artifactPath: options.phaseOverviewPath,
            reviewBoundary: "phase-authoring-readiness",
            context: {
                milestoneSlug: task.coverage.milestoneSlug,
                taskSlug: task.coverage.taskSlug,
                validationInputFingerprint: task.validationInputCoverage.fingerprint
            }
        })));
    }
    const requiredComplete = baseInspection.contractState !== "invalid"
        && tasks.every((entry) => entry.coverage.requiredComplete);
    return {
        coverage: {
            contractPath: task_contract_impact_1.TASK_CONTRACT_IMPACT_PATH,
            contractState: baseInspection.contractState,
            schemaVersion: baseInspection.schemaVersion,
            unknownPolicy: baseInspection.unknownPolicy,
            enforced: baseInspection.contractState !== "absent",
            taskCount: tasks.length,
            uniqueTargetCount: uniqueTargets.length,
            coveredTargetCount: baseInspection.contractState === "valid"
                ? uniqueTargets.length - unknownPaths.length
                : 0,
            unknownTargetCount: unknownPaths.length,
            unknownPaths,
            requiredComplete,
            tasks: tasks.map((entry) => entry.coverage),
            readOnly: true
        },
        findings
    };
}
function createPhaseContractImpactFinding(options) {
    return (0, output_1.createBlockingValidationFinding)({
        code: options.code,
        message: options.message,
        path: task_contract_impact_1.TASK_CONTRACT_IMPACT_PATH,
        affectedPaths: uniqueSorted(options.affectedPaths).map((affectedPath) => ({
            role: "declared-target",
            path: affectedPath,
            description: "Phase Scaffold Evidence requires exact contract-impact coverage before milestone creation."
        })),
        blockingReason: "invalid-command-input",
        recovery: `Complete an explicitly authorized contract-impact coverage task for every listed path, then rerun phase review --review-mode readiness. This review performs no repair writes.`,
        evidence: {
            category: "planning-review",
            details: {
                reviewBoundary: "phase-authoring-readiness",
                requiresRefinement: true,
                noWriteRequired: true,
                ...options.details
            }
        }
    });
}
function uniqueSorted(values) {
    return [...new Set(values)].sort((left, right) => left.localeCompare(right));
}
