"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.reviewImplementationSummary = reviewImplementationSummary;
exports.createImplementationSummaryReviewReceipt = createImplementationSummaryReviewReceipt;
exports.createTaskCloseActions = createTaskCloseActions;
exports.sha256ReviewSubject = sha256ReviewSubject;
exports.canonicalReviewJson = canonicalReviewJson;
// Responsibility-focused implementation extracted from the public compatibility facade.
const node_crypto_1 = require("node:crypto");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const errors_1 = require("../../errors");
const declared_target_paths_1 = require("../../validation/declared-target-paths");
const documentation_path_classifier_1 = require("../../validation/documentation-path-classifier");
const artifact_policy_projection_1 = require("../artifact-policy-projection");
const front_matter_utils_1 = require("../front-matter-utils");
const evidence_review_1 = require("../reconciliation/evidence-review");
const selector_evidence_1 = require("../reconciliation/selector-evidence");
const semantic_placeholder_1 = require("../semantic-placeholder");
const task_cycle_runtime_attribution_1 = require("../task-cycle-runtime-attribution");
const task_lifecycle_1 = require("../task-lifecycle");
const task_validation_1 = require("../task-validation");
const task_waivers_1 = require("../task-waivers");
const context_1 = require("./context");
const contracts_1 = require("./contracts");
const document_paths_1 = require("./document-paths");
const document_rendering_1 = require("./document-rendering");
const evidence_1 = require("./evidence");
const renderers_1 = require("./renderers");
function reviewImplementationSummary(repositoryRoot, options) {
    const taskDefinitionPath = (0, document_paths_1.resolveRepositoryPath)(repositoryRoot, options.taskDefinitionPath, "task-definition");
    if (!node_fs_1.default.existsSync(taskDefinitionPath.absolute)) {
        throw (0, errors_1.createUsageError)(`Task definition not found at '${taskDefinitionPath.relative}'.`, ["Pass an existing repository-relative --task-definition path."]);
    }
    const taskDefinitionText = node_fs_1.default.readFileSync(taskDefinitionPath.absolute, "utf8");
    const taskDocument = (0, document_paths_1.parseMarkdownDocument)(taskDefinitionPath.relative, taskDefinitionText);
    (0, context_1.assertArtifactType)(taskDocument.frontMatterLines, taskDefinitionPath.relative, "task_definition");
    const context = (0, context_1.parseTaskDefinitionContext)(taskDefinitionPath.relative, taskDocument, {
        allowMissingExecutionMode: true
    });
    const declaredTargetPathEvidence = (0, declared_target_paths_1.readTaskDeclaredTargetPathEvidence)(taskDefinitionPath.relative, taskDefinitionText);
    const implementationSummaryPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(taskDefinitionPath.relative), "implementation-summary.md"));
    const implementationSummaryAbsolute = node_path_1.default.join(repositoryRoot, implementationSummaryPath);
    if (!node_fs_1.default.existsSync(implementationSummaryAbsolute)) {
        throw (0, errors_1.createUsageError)(`Paired implementation summary not found at '${implementationSummaryPath}'.`, ["Run day-shift implementation-summary build first or restore the paired implementation-summary.md artifact."]);
    }
    const summaryText = node_fs_1.default.readFileSync(implementationSummaryAbsolute, "utf8");
    const summaryDocument = (0, document_paths_1.parseMarkdownDocument)(implementationSummaryPath, summaryText);
    (0, context_1.assertArtifactType)(summaryDocument.frontMatterLines, implementationSummaryPath, "implementation_summary");
    const duplicateImplementationSummaryPaths = (0, document_paths_1.collectDuplicateImplementationSummaryPaths)(repositoryRoot, taskDefinitionPath.relative, implementationSummaryPath);
    const missingEvidence = [];
    const placeholderResidue = [];
    const alignmentIssues = [];
    const reviewNotes = [];
    const changedPathPlaceholderFindings = [];
    const preliminaryLifecycle = (0, task_lifecycle_1.projectImplementationSummaryLifecycle)(summaryText).value;
    const preliminaryAttempt = preliminaryLifecycle.currentAttempt;
    const currentAttemptValidations = preliminaryAttempt?.attemptId === null
        || preliminaryAttempt?.attemptId === undefined
        ? []
        : (0, task_validation_1.readTaskValidationResults)(implementationSummaryPath, summaryText)
            .filter((validation) => validation.attemptId === preliminaryAttempt.attemptId);
    const validationIdentityProjection = (0, task_validation_1.projectTaskValidationIdentities)(currentAttemptValidations);
    const reviewWaiverApplicable = preliminaryAttempt?.reviewDisposition === "waived"
        && preliminaryAttempt.reviewWaiverId !== null
        && (0, task_waivers_1.findApplicableTaskWaiver)(implementationSummaryPath, summaryText, {
            waiverType: "review",
            subjectId: context.task,
            attemptId: preliminaryAttempt.attemptId,
            evaluatedAt: new Date().toISOString(),
            authorityRequired: true,
            waiverId: preliminaryAttempt.reviewWaiverId
        })?.applicable === true;
    const lifecyclePair = (0, task_lifecycle_1.projectTaskLifecyclePair)({
        taskDefinition: taskDefinitionText,
        implementationSummary: summaryText,
        reviewWaiverApplicable
    });
    const implementationStatus = lifecyclePair.implementationStatus
        ?? lifecyclePair.summary?.legacyImplementationStatus
        ?? null;
    const reviewDisposition = lifecyclePair.reviewDisposition
        ?? lifecyclePair.summary?.legacyReviewDisposition
        ?? null;
    const artifactStatus = (0, selector_evidence_1.readTopLevelField)(summaryDocument.frontMatterLines, "status")?.trim() ?? null;
    const taskStatus = (0, selector_evidence_1.readTopLevelField)(taskDocument.frontMatterLines, "status")?.trim() ?? null;
    const taskReadiness = (0, selector_evidence_1.readTopLevelField)(taskDocument.frontMatterLines, "readiness")?.trim() ?? null;
    const taskPolicy = (0, artifact_policy_projection_1.projectArtifactPolicy)(taskDefinitionText);
    const summaryPolicy = (0, artifact_policy_projection_1.projectArtifactPolicy)(summaryText);
    const reviewHandoff = (0, renderers_1.implementationSummaryReviewHandoff)(taskPolicy, validationIdentityProjection);
    const summaryExecutionMode = summaryPolicy.evidenceProfile;
    alignmentIssues.push(...taskPolicy.blockingFindings.map((finding) => finding.message));
    alignmentIssues.push(...summaryPolicy.blockingFindings.map((finding) => finding.message));
    alignmentIssues.push(...lifecyclePair.blockingFindings.map((finding) => finding.message));
    (0, selector_evidence_1.assertMatchingPlanningIdentity)(context, summaryDocument.frontMatterLines, implementationSummaryPath, alignmentIssues, (0, document_rendering_1.implementationSummaryIdentityKeys)(context));
    const upstreamTaskDefinition = (0, selector_evidence_1.readUpstreamField)(summaryDocument.frontMatterLines, "task_definition")?.trim() ?? null;
    if (upstreamTaskDefinition !== taskDefinitionPath.relative) {
        alignmentIssues.push(`Upstream task_definition should point to '${taskDefinitionPath.relative}', found '${upstreamTaskDefinition ?? "(missing)"}'.`);
    }
    if (context.executionMode === "") {
        alignmentIssues.push("Task definition evidence_profile is missing and no legacy execution_mode alias is available.");
    }
    else if (!(0, selector_evidence_1.isAllowedExecutionMode)(context.executionMode)) {
        alignmentIssues.push(`Task definition evidence_profile uses unsupported value '${context.executionMode}'.`);
    }
    if (summaryExecutionMode === null) {
        alignmentIssues.push("Implementation summary evidence_profile is missing and no legacy execution_mode alias is available.");
    }
    else if (!(0, selector_evidence_1.isAllowedExecutionMode)(summaryExecutionMode)) {
        alignmentIssues.push(`Implementation summary evidence_profile uses unsupported value '${summaryExecutionMode}'.`);
    }
    else if (summaryExecutionMode !== context.executionMode) {
        alignmentIssues.push(`Implementation summary evidence_profile '${summaryExecutionMode}' does not match task definition evidence_profile '${context.executionMode}'.`);
    }
    if (context.executionMode === "contract" && (0, selector_evidence_1.hasRuntimeImplementationClaim)(summaryDocument.sections)) {
        alignmentIssues.push("Contract-mode implementation summary claims runtime implementation; use runtime or hybrid mode for runtime behavior changes, or reword the summary as contract evidence only.");
    }
    for (const duplicateImplementationSummaryPath of duplicateImplementationSummaryPaths) {
        alignmentIssues.push(`Duplicate or misplaced implementation-summary closeout artifact '${duplicateImplementationSummaryPath}' was found under the selected task directory; keep the canonical paired summary at '${implementationSummaryPath}' and correct the duplicate with an explicit follow-up command.`);
    }
    for (const sectionName of contracts_1.IMPLEMENTATION_SUMMARY_SECTIONS) {
        const sectionText = summaryDocument.sections.get(sectionName);
        if (sectionText === undefined) {
            missingEvidence.push(`Missing required section '${sectionName}'.`);
            continue;
        }
        if (sectionName !== "Changed Paths" && (0, semantic_placeholder_1.hasSemanticPlaceholderContent)(sectionText)) {
            placeholderResidue.push(`Section '${sectionName}' still contains placeholder content.`);
        }
    }
    const changedPathsText = summaryDocument.sections.get("Changed Paths");
    if (changedPathsText === undefined) {
        missingEvidence.push("Changed Paths does not list implemented repository paths yet.");
    }
    else {
        const changedPathEvidence = (0, evidence_1.extractSummaryChangedPathEvidence)(changedPathsText);
        const concreteChangedPaths = changedPathEvidence
            .filter((entry) => entry.state === "path" && entry.path !== undefined)
            .map((entry) => entry.path);
        if (concreteChangedPaths.length === 0) {
            missingEvidence.push("Changed Paths does not list concrete repository-relative changed paths.");
        }
        if ((context.executionMode === "runtime" || context.executionMode === "hybrid") && concreteChangedPaths.length > 0) {
            const runtimeEligibleChangedPaths = concreteChangedPaths.filter((changedPath) => (0, documentation_path_classifier_1.classifyDocumentationPath)(changedPath, {
                declaredTargetRole: (0, declared_target_paths_1.resolveDeclaredTargetPathRole)(declaredTargetPathEvidence.evidence, changedPath)
            }).runtimeEligible);
            if (runtimeEligibleChangedPaths.length === 0) {
                missingEvidence.push("Runtime and hybrid implementation summaries must include at least one runtime-eligible changed path; current Changed Paths evidence is documentation-only.");
            }
            else {
                const explicitRuntimeTargetPaths = declaredTargetPathEvidence.explicitTargetPaths.filter((targetPath) => (0, documentation_path_classifier_1.classifyDocumentationPath)(targetPath, {
                    declaredTargetRole: (0, declared_target_paths_1.resolveDeclaredTargetPathRole)(declaredTargetPathEvidence.evidence, targetPath)
                }).runtimeEligible);
                const deviationsText = summaryDocument.sections.get("Deviations");
                if (explicitRuntimeTargetPaths.length === 0) {
                    alignmentIssues.push("Task definition does not provide concrete runtime-eligible Runtime Delta target paths for runtime target-alignment review.");
                }
                else {
                    for (const changedPath of runtimeEligibleChangedPaths) {
                        if ((0, document_paths_1.pathOverlapsAnyTarget)(changedPath, explicitRuntimeTargetPaths)) {
                            continue;
                        }
                        const matchingDeviationTarget = explicitRuntimeTargetPaths.find((targetPath) => (0, document_paths_1.hasRuntimeTargetReplacementDeviation)(deviationsText, targetPath, changedPath));
                        if (matchingDeviationTarget !== undefined) {
                            reviewNotes.push(`Runtime changed path '${changedPath}' replaces declared Runtime Delta target '${matchingDeviationTarget}' with explicit deviation evidence.`);
                            continue;
                        }
                        alignmentIssues.push(`Runtime changed path '${changedPath}' does not overlap declared Runtime Delta target paths (${explicitRuntimeTargetPaths.join(", ")}) and requires explicit deviation evidence naming both the declared target and replacement changed path.`);
                    }
                }
            }
        }
        for (const entry of changedPathEvidence) {
            if (entry.state !== "path") {
                missingEvidence.push(entry.message);
            }
            if (entry.state === "placeholder") {
                changedPathPlaceholderFindings.push(entry);
            }
        }
        const explicitTargetPaths = declaredTargetPathEvidence.explicitTargetPaths;
        if (concreteChangedPaths.length > 0 && explicitTargetPaths.length === 0) {
            alignmentIssues.push("Task definition does not provide concrete Implementation Target Paths for changed-path overlap review.");
        }
        const deviationsText = summaryDocument.sections.get("Deviations");
        const hasDeviationJustification = (0, document_paths_1.hasConcreteDeviationJustification)(deviationsText);
        for (const changedPath of concreteChangedPaths) {
            if (explicitTargetPaths.length === 0 || (0, document_paths_1.pathOverlapsAnyTarget)(changedPath, explicitTargetPaths)) {
                continue;
            }
            if (hasDeviationJustification) {
                reviewNotes.push(`Changed path '${changedPath}' is outside declared task target paths but the Deviations section records justification.`);
                continue;
            }
            alignmentIssues.push(`Changed path '${changedPath}' is outside declared task target paths (${explicitTargetPaths.join(", ")}) and requires concrete deviation justification.`);
        }
    }
    const validationText = summaryDocument.sections.get("Validation Performed");
    if (validationText === undefined || (0, semantic_placeholder_1.hasSemanticPlaceholderContent)(validationText)) {
        missingEvidence.push("Validation Performed does not record any executed validation evidence.");
    }
    else if ((context.executionMode === "runtime" || context.executionMode === "hybrid")
        && (0, evidence_1.hasValidationExceptionIntent)(validationText)
        && !(0, evidence_1.hasCompleteStructuredValidationException)(validationText)) {
        missingEvidence.push("Runtime and hybrid validation exceptions must record planned command, blocker, substitute evidence, residual risk, and follow-up validation path.");
    }
    else if (!(0, evidence_1.hasConcreteValidationEvidence)(validationText)) {
        missingEvidence.push("Validation Performed only provides status-level validation claims; record commands, changed-file inspection, or an explicit validation exception.");
    }
    const acceptanceCriteriaResultsText = summaryDocument.sections.get("Acceptance Criteria Results");
    if (acceptanceCriteriaResultsText !== undefined
        && !(0, semantic_placeholder_1.hasSemanticPlaceholderContent)(acceptanceCriteriaResultsText)
        && !(0, evidence_1.hasConcreteAcceptanceEvidence)(acceptanceCriteriaResultsText)) {
        missingEvidence.push("Acceptance Criteria Results only assert completion; connect each result to changed paths, validation, commands, or concrete implementation evidence.");
    }
    missingEvidence.push(...(0, task_cycle_runtime_attribution_1.reviewTaskCycleRuntimeAttribution)(repositoryRoot, {
        taskDefinitionPath: taskDefinitionPath.relative,
        taskMarkdownText: taskDefinitionText,
        summaryMarkdownText: summaryText
    }));
    missingEvidence.push(...(0, task_validation_1.reviewCurrentAttemptValidationEvidence)(repositoryRoot, implementationSummaryPath, summaryText));
    if (implementationStatus !== "completed") {
        reviewNotes.push(`implementation_status is '${implementationStatus ?? "(missing)"}', so task closeout evidence is not complete yet.`);
    }
    if (implementationStatus === "completed"
        && reviewDisposition !== "accepted"
        && reviewDisposition !== "accepted_with_follow_up"
        && !(reviewDisposition === "waived" && reviewWaiverApplicable)) {
        reviewNotes.push(`implementation_status is 'completed' but current review_disposition is '${reviewDisposition ?? "(missing)"}'; accepted review evidence is required before task closure.`);
    }
    const closeoutEvidenceStatus = missingEvidence.length === 0
        && placeholderResidue.length === 0
        && alignmentIssues.length === 0
        && implementationStatus === "completed"
        && (reviewDisposition === "accepted"
            || reviewDisposition === "accepted_with_follow_up"
            || (reviewDisposition === "waived" && reviewWaiverApplicable))
        ? "sufficient"
        : "insufficient";
    const blockingIssues = [
        ...missingEvidence,
        ...placeholderResidue,
        ...alignmentIssues
    ];
    const warnings = [...reviewNotes];
    const metadataHygieneFollowUps = [];
    const availableReviewWaiver = preliminaryAttempt?.attemptId === null
        || preliminaryAttempt?.attemptId === undefined
        ? null
        : (0, task_waivers_1.findApplicableTaskWaiver)(implementationSummaryPath, summaryText, {
            waiverType: "review",
            subjectId: context.task,
            attemptId: preliminaryAttempt.attemptId,
            evaluatedAt: new Date().toISOString(),
            authorityRequired: true
        });
    const reviewReceipt = createImplementationSummaryReviewReceipt({
        taskDefinitionPath: taskDefinitionPath.relative,
        implementationSummaryPath,
        taskText: taskDefinitionText,
        summaryText,
        attemptId: preliminaryAttempt?.attemptId ?? null,
        implementationStatus,
        reviewDisposition,
        blockingIssueCount: blockingIssues.length,
        pairTerminal: lifecyclePair.terminal,
        reviewWaiverApplicable: reviewWaiverApplicable || availableReviewWaiver?.applicable === true
    });
    const reviewResultPath = options.reviewResultPath?.trim() || "implementation-summary-review.json";
    const taskCloseActions = reviewReceipt?.authorizes.includes("close") === true
        ? createTaskCloseActions(taskDefinitionPath.relative, reviewResultPath)
        : null;
    if (closeoutEvidenceStatus === "sufficient" && taskStatus !== "completed") {
        metadataHygieneFollowUps.push(`Accepted completed implementation evidence permits explicit closure while preserving readiness='${taskReadiness ?? "(missing)"}' until that explicit close transaction; task status is '${taskStatus ?? "(missing)"}'. Preview with: ${taskCloseActions?.dryRun.argv?.join(" ") ?? "(fresh receipt required)"}. Apply by using the emitted apply argv, which omits --dry-run.`);
    }
    const recoveryGuidance = (0, evidence_review_1.buildEvidenceReviewRecoveryGuidance)({
        artifactPath: implementationSummaryPath,
        reviewKind: "implementation-summary",
        blockingIssues,
        warnings,
        metadataHygieneFollowUps
    });
    const findings = (0, evidence_review_1.buildEvidenceReviewFindings)({
        artifactPath: implementationSummaryPath,
        reviewKind: "implementation-summary",
        blockingIssues,
        warnings,
        metadataHygieneFollowUps,
        changedPathPlaceholderFindings
    });
    return {
        taskDefinitionPath: taskDefinitionPath.relative,
        implementationSummaryPath,
        implementationStatus,
        artifactStatus,
        closeoutEvidenceStatus,
        missingEvidence,
        placeholderResidue,
        alignmentIssues,
        reviewNotes,
        blockingIssues,
        warnings,
        metadataHygieneFollowUps,
        recoveryGuidance,
        findings,
        validationIdentityProjection,
        reviewHandoff,
        reviewReceipt,
        taskCloseActions
    };
}
function createImplementationSummaryReviewReceipt(options) {
    if (options.attemptId === null
        || options.implementationStatus !== "completed"
        || options.blockingIssueCount !== 0
        || options.reviewDisposition === "blocked"
        || options.reviewDisposition === "changes_requested"
        || options.reviewDisposition === "cancelled"
        || (options.reviewDisposition !== "pending"
            && options.reviewDisposition !== "accepted"
            && options.reviewDisposition !== "accepted_with_follow_up"
            && options.reviewDisposition !== "waived")) {
        return null;
    }
    if (options.reviewDisposition === "waived" && !options.reviewWaiverApplicable) {
        return null;
    }
    const authorizes = ["disposition"];
    if (!options.pairTerminal
        && (options.reviewDisposition === "accepted"
            || options.reviewDisposition === "accepted_with_follow_up"
            || options.reviewDisposition === "waived"
            || options.reviewWaiverApplicable)) {
        authorizes.push("close");
    }
    const reviewDisposition = options.reviewDisposition;
    const subject = {
        schemaVersion: contracts_1.IMPLEMENTATION_SUMMARY_REVIEW_RECEIPT_PROTOCOL_VERSION,
        taskDefinitionPath: options.taskDefinitionPath,
        implementationSummaryPath: options.implementationSummaryPath,
        taskRevision: sha256ReviewSubject(options.taskText),
        implementationSummaryRevision: sha256ReviewSubject(options.summaryText),
        attemptId: options.attemptId,
        implementationStatus: "completed",
        reviewDisposition,
        blockerCount: 0,
        authorizes
    };
    return {
        ...subject,
        reviewReceiptId: `implementation-summary-review-${sha256ReviewSubject(canonicalReviewJson(subject)).slice(0, 24)}`
    };
}
function createTaskCloseActions(taskDefinitionPath, reviewResultPath) {
    const base = [
        "day-shift",
        "task",
        "close",
        "--task-definition",
        taskDefinitionPath,
        "--review-result",
        reviewResultPath
    ];
    return {
        dryRun: (0, errors_1.createDescriptorBackedRecoveryAction)({
            command: "task close",
            argv: [...base, "--dry-run"],
            explanation: "Preview the receipt-bound canonical terminal pair transaction.",
            selectedArtifactPath: taskDefinitionPath
        }),
        apply: (0, errors_1.createDescriptorBackedRecoveryAction)({
            command: "task close",
            argv: base,
            explanation: "Apply the exact receipt-bound canonical terminal pair transaction.",
            selectedArtifactPath: taskDefinitionPath
        })
    };
}
function sha256ReviewSubject(value) {
    return (0, node_crypto_1.createHash)("sha256").update(Buffer.from(value)).digest("hex");
}
function canonicalReviewJson(value) {
    if (Array.isArray(value)) {
        return `[${value.map((item) => canonicalReviewJson(item)).join(",")}]`;
    }
    if (value !== null && typeof value === "object") {
        const record = value;
        return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalReviewJson(record[key])}`).join(",")}}`;
    }
    return JSON.stringify(value);
}
