"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createReconciliationReviewCommand = createReconciliationReviewCommand;
exports.applyReconciliationContractReview = applyReconciliationContractReview;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const errors_1 = require("../../../lib/errors");
const implementation_summary_reconciliation_1 = require("../../../lib/planning/implementation-summary-reconciliation");
const output_1 = require("../../../lib/output");
const review_output_contracts_1 = require("../../../lib/planning/review-output-contracts");
const reconciliation_resolution_1 = require("../../../lib/planning/reconciliation-resolution");
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
const global_format_1 = require("../global-format");
async function createReconciliationReviewCommand() {
    const { Command } = await import("commander");
    const command = new Command("review");
    command
        .description("Evaluate reconciliation evidence as a read-only, no-write surface; milestone rollup is the default, task-local review is an explicit exception.")
        .option("--milestone-overview <path>", "Repository-relative path to the milestone overview whose paired reconciliation should be reviewed.")
        .option("--task-definition <path>", "Repository-relative task-definition.md path for an explicit task-level reconciliation exception.")
        .option("--rationale <text>", "Required rationale when using --task-definition for an explicit task-level reconciliation exception.")
        .action((_, commandInstance) => {
        const format = (0, output_1.resolveOutputFormat)((0, global_format_1.getGlobalFormat)(commandInstance));
        if (format === null) {
            throw (0, errors_1.createUsageError)("Output format must be one of: text, json.", [`Received: ${String((0, global_format_1.getGlobalFormat)(commandInstance))}`]);
        }
        const repositoryContext = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const options = commandInstance.opts();
        const coreResult = (0, implementation_summary_reconciliation_1.reviewReconciliation)(repositoryContext.root, {
            milestoneOverviewPath: options.milestoneOverview,
            taskDefinitionPath: options.taskDefinition,
            taskReconciliationRationale: options.rationale
        });
        const result = applyReconciliationContractReview(repositoryContext.root, coreResult);
        (0, output_1.emitSuccess)({
            command: "reconciliation review",
            format,
            text: (0, implementation_summary_reconciliation_1.renderReconciliationReviewResult)(result),
            data: {
                repositoryRoot: repositoryContext.root,
                detectionSource: repositoryContext.detectionSource,
                readOnly: true,
                writeCapable: false,
                noWriteBoundary: (0, review_output_contracts_1.getReviewOutputContract)("reconciliation review").noWriteBoundary,
                reviewOutputContract: (0, review_output_contracts_1.getReviewOutputContract)("reconciliation review"),
                mode: result.mode,
                milestoneOverviewPath: result.milestoneOverviewPath,
                taskDefinitionPath: result.taskDefinitionPath,
                reconciliationPath: result.reconciliationPath,
                reconciliationStatus: result.reconciliationStatus,
                artifactStatus: result.artifactStatus,
                closureEvidenceStatus: result.closureEvidenceStatus,
                evidenceGaps: result.evidenceGaps,
                placeholderResidue: result.placeholderResidue,
                alignmentIssues: result.alignmentIssues,
                reviewConcerns: result.reviewConcerns,
                blockingIssues: result.blockingIssues,
                warnings: result.warnings,
                metadataHygieneFollowUps: result.metadataHygieneFollowUps,
                recoveryGuidance: result.recoveryGuidance,
                headingContract: result.headingContract,
                resolutionEvidence: result.resolutionEvidence,
                reviewReceipt: result.reviewReceipt
            },
            findings: [...result.findings]
        });
    });
    return command;
}
function applyReconciliationContractReview(repositoryRoot, result) {
    const reconciliationAbsolutePath = node_path_1.default.join(repositoryRoot, result.reconciliationPath);
    const rawHeadingContract = (0, reconciliation_resolution_1.reviewReconciliationHeadingContract)(node_fs_1.default.readFileSync(reconciliationAbsolutePath, "utf8"), result.mode);
    const preserveCompletedLegacyResolvedLane = result.reconciliationStatus === "completed" &&
        result.artifactStatus === "completed" &&
        rawHeadingContract.resolvedFindingsCount === 0;
    const headingContract = preserveCompletedLegacyResolvedLane
        ? {
            ...rawHeadingContract,
            issues: rawHeadingContract.issues.filter((issue) => !(issue.code === "RECONCILIATION_REVIEW_HEADING_MISSING" &&
                issue.message.includes("'Resolved Findings'")))
        }
        : rawHeadingContract;
    const resolutionEvidence = (0, reconciliation_resolution_1.reviewReconciliationResolutionEvidence)(repositoryRoot, collectResolutionContextPaths(repositoryRoot, result), result.reconciliationPath);
    const contractIssues = uniqueContractIssues([
        ...headingContract.issues,
        ...resolutionEvidence.issues
    ]);
    const issueMessages = contractIssues.map((issue) => issue.message);
    const blockingIssues = uniqueStrings([
        ...result.blockingIssues,
        ...issueMessages
    ]);
    const findings = [
        ...result.findings,
        ...contractIssues.map((issue) => (0, output_1.createBlockingValidationFinding)({
            code: issue.code,
            message: issue.message,
            path: result.reconciliationPath,
            blockingReason: "invalid-command-input",
            recovery: `Reconciliation review is read-only and applied no writes; repair '${result.reconciliationPath}' ` +
                "through an explicit reconciliation authoring or build step, then rerun review.",
            evidence: {
                category: "planning-review",
                details: {
                    category: issue.code.includes("HEADING")
                        ? "heading-contract"
                        : "resolution-evidence",
                    blocking: true,
                    reviewKind: "reconciliation",
                    artifactPath: result.reconciliationPath,
                    resolutionAttribution: resolutionEvidence.attribution
                }
            }
        }))
    ];
    return {
        ...result,
        closureEvidenceStatus: contractIssues.length > 0 ? "insufficient" : result.closureEvidenceStatus,
        evidenceGaps: uniqueStrings([
            ...result.evidenceGaps,
            ...issueMessages
        ]),
        blockingIssues,
        recoveryGuidance: contractIssues.length === 0
            ? result.recoveryGuidance
            : uniqueStrings([
                ...result.recoveryGuidance,
                `Repair the canonical heading or Resolved Findings evidence in '${result.reconciliationPath}', then rerun reconciliation review.`
            ]),
        findings,
        reviewReceipt: contractIssues.length > 0 ? null : result.reviewReceipt,
        headingContract,
        resolutionEvidence
    };
}
function collectResolutionContextPaths(repositoryRoot, result) {
    if (result.mode === "task" || result.milestoneOverviewPath === null) {
        return [result.reconciliationPath];
    }
    const milestoneDirectory = node_path_1.default.dirname(result.milestoneOverviewPath);
    const milestonesDirectory = node_path_1.default.dirname(milestoneDirectory);
    const milestonesAbsolutePath = node_path_1.default.join(repositoryRoot, milestonesDirectory);
    if (!node_fs_1.default.existsSync(milestonesAbsolutePath)) {
        return [result.reconciliationPath];
    }
    const reconciliationPaths = node_fs_1.default.readdirSync(milestonesAbsolutePath, {
        withFileTypes: true
    }).flatMap((entry) => {
        if (!entry.isDirectory())
            return [];
        const candidate = node_path_1.default.posix.join(milestonesDirectory.replace(/\\/g, "/"), entry.name, "reconciliation.md");
        return node_fs_1.default.existsSync(node_path_1.default.join(repositoryRoot, candidate)) ? [candidate] : [];
    });
    return uniqueStrings([
        ...reconciliationPaths,
        result.reconciliationPath
    ]).sort((left, right) => left.localeCompare(right));
}
function uniqueStrings(values) {
    return values.filter((value, index) => values.indexOf(value) === index);
}
function uniqueContractIssues(issues) {
    return issues.filter((issue, index) => issues.findIndex((candidate) => candidate.code === issue.code && candidate.message === issue.message) === index);
}
