"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveTaskBaselineContext = resolveTaskBaselineContext;
exports.previewTaskCycleRuntimeBaseline = previewTaskCycleRuntimeBaseline;
exports.applyTaskCycleRuntimeBaseline = applyTaskCycleRuntimeBaseline;
exports.captureTaskCycleRuntimeBaseline = captureTaskCycleRuntimeBaseline;
const node_crypto_1 = require("node:crypto");
const node_fs_1 = __importDefault(require("node:fs"));
const errors_1 = require("../../errors");
const mutation_preconditions_1 = require("../../filesystem/mutation-preconditions");
const repository_transaction_1 = require("../../filesystem/repository-transaction");
const runtime_contract_1 = require("../../runtime/runtime-contract");
const declared_target_paths_1 = require("../../validation/declared-target-paths");
const artifact_policy_projection_1 = require("../artifact-policy-projection");
const planning_document_utils_1 = require("../planning-document-utils");
const task_lifecycle_1 = require("../task-lifecycle");
const validation_input_coverage_1 = require("../validation-input-coverage");
const task_lifecycle_timestamps_1 = require("../task-lifecycle-timestamps");
const baseline_planning_1 = require("./baseline-planning");
const contracts_1 = require("./contracts");
const predecessor_evidence_1 = require("./predecessor-evidence");
const repository_support_1 = require("./repository-support");
const serialization_1 = require("./serialization");
const supplemental_baseline_1 = require("./supplemental-baseline");
const target_inspection_1 = require("./target-inspection");
function resolveTaskBaselineContext(repositoryRoot, options) {
    const pair = (0, repository_support_1.resolveTaskPair)(repositoryRoot, options.taskDefinitionPath);
    const taskDefinitionPath = pair.task.repositoryRelativePath;
    const implementationSummaryPath = pair.summary.repositoryRelativePath;
    (0, repository_support_1.assertIdentity)("task-cycle", options.taskCycleId);
    (0, repository_support_1.assertIdentity)("checkpoint", options.checkpointId);
    const taskText = node_fs_1.default.readFileSync(pair.task.runtimePath, "utf8");
    const summaryText = node_fs_1.default.readFileSync(pair.summary.runtimePath, "utf8");
    const parsed = (0, planning_document_utils_1.parseMarkdownFrontMatter)(taskText);
    if (!parsed.hasFrontMatter || (0, planning_document_utils_1.readTopLevelField)(parsed.frontMatterLines, "artifact_type") !== "task_definition") {
        throw (0, errors_1.createUsageError)(`Artifact '${taskDefinitionPath}' must be a task_definition.`);
    }
    const readiness = (0, planning_document_utils_1.readTopLevelField)(parsed.frontMatterLines, "readiness")?.trim();
    if (readiness !== "ready_to_implement" && readiness !== "ready to implement") {
        throw (0, errors_1.createUsageError)(`Task baseline capture requires readiness 'ready_to_implement', found '${readiness ?? "(missing)"}'.`, ["Run task readiness-review, then apply the explicit readiness update before baseline capture."]);
    }
    const executionMode = (0, artifact_policy_projection_1.projectArtifactPolicy)(taskText).evidenceProfile;
    if (executionMode !== "runtime" && executionMode !== "hybrid") {
        throw (0, errors_1.createUsageError)(`Task baseline capture requires evidence_profile runtime or hybrid, found '${executionMode ?? "(missing)"}'.`);
    }
    const runtimePreconditions = (0, contracts_1.evaluateTaskRuntimeBaselinePreconditions)({
        artifactPath: taskDefinitionPath,
        frontMatterLines: parsed.frontMatterLines,
        markdownText: taskText,
        evidenceProfile: executionMode
    });
    if (runtimePreconditions.findings.length > 0) {
        throw new contracts_1.TaskBaselineRuntimeAcceptanceContractError(taskDefinitionPath, runtimePreconditions.issues);
    }
    const legacyBaseline = (0, baseline_planning_1.readTaskCycleRuntimeBaseline)(taskDefinitionPath, taskText);
    const restoredTaskText = legacyBaseline === null
        ? taskText
        : (0, serialization_1.removeFrontMatterBlock)(taskText, contracts_1.BASELINE_BLOCK);
    const projection = (0, task_lifecycle_1.projectTaskLifecyclePair)({
        taskDefinition: restoredTaskText,
        implementationSummary: summaryText
    });
    if (projection.blockingFindings.length > 0) {
        throw (0, errors_1.createUsageError)("Task baseline requires a valid open canonical attempt and applicable readiness authorization.", projection.blockingFindings.map((finding) => finding.message));
    }
    const currentAttempt = projection.summary?.currentAttempt ?? null;
    const authorization = projection.task.readinessAuthorization;
    if (projection.task.status !== "draft"
        || currentAttempt === null
        || currentAttempt.attemptId === null
        || currentAttempt.closedAt !== null
        || currentAttempt.readinessReviewId === null
        || !authorization.complete
        || !authorization.valid
        || !authorization.applicable
        || !(0, task_lifecycle_1.isTaskReadinessAuthorizationRevisionApplicable)(restoredTaskText, authorization.taskRevision)) {
        throw (0, errors_1.createUsageError)("Task baseline requires one open current attempt bound to complete revision-applicable readiness authorization.", ["No task or implementation-summary bytes were written."]);
    }
    if (currentAttempt.attemptId !== options.taskCycleId
        || currentAttempt.readinessReviewId !== options.checkpointId
        || authorization.id !== options.checkpointId) {
        throw (0, errors_1.createUsageError)("Baseline compatibility identities must exactly match current attempt_id and readiness_review_id.", [
            `Current attempt_id: ${currentAttempt.attemptId}`,
            `Current readiness_review_id: ${currentAttempt.readinessReviewId}`,
            "No files were written."
        ]);
    }
    const declaredTargets = (0, declared_target_paths_1.readTaskDeclaredTargetPathEvidence)(taskDefinitionPath, taskText);
    const targetIssues = declaredTargets.evidence.filter((entry) => entry.state !== "explicit");
    if (declaredTargets.explicitTargetPaths.length === 0 || targetIssues.length > 0) {
        throw (0, errors_1.createUsageError)(`Task baseline capture requires concrete, unique declared target paths at '${taskDefinitionPath}'.`, targetIssues.map((entry) => entry.message));
    }
    const validationInputInspection = (0, validation_input_coverage_1.inspectTaskDocumentValidationInputCoverage)({
        repositoryRoot: pair.repositoryRoot,
        taskDefinitionPath,
        taskText: restoredTaskText
    });
    if (!validationInputInspection.coverage.complete) {
        throw (0, errors_1.createUsageError)(`Task baseline validation-input preflight is incomplete at '${taskDefinitionPath}'.`, [
            ...validationInputInspection.coverage.issues.map((issue) => issue.message),
            "No task, implementation-summary, baseline, or runtime-attribution bytes were written."
        ]);
    }
    const contractImpact = validationInputInspection.contractImpact;
    const suppliedContractImpactFingerprint = options.contractImpactFingerprint?.trim() || null;
    if (!contractImpact.requiredComplete) {
        throw new contracts_1.TaskBaselineContractImpactError({
            taskDefinitionPath,
            contractImpact,
            suppliedFingerprint: suppliedContractImpactFingerprint,
            reason: `Task baseline contract-impact preflight is incomplete at '${taskDefinitionPath}'.`
        });
    }
    if (contractImpact.contractState === "valid"
        && suppliedContractImpactFingerprint !== contractImpact.fingerprint) {
        throw new contracts_1.TaskBaselineContractImpactError({
            taskDefinitionPath,
            contractImpact,
            suppliedFingerprint: suppliedContractImpactFingerprint,
            reason: suppliedContractImpactFingerprint === null
                ? `Task baseline requires the current readiness contract-impact fingerprint '${contractImpact.fingerprint}'.`
                : `Task baseline contract-impact fingerprint is stale; expected '${contractImpact.fingerprint}' and received '${suppliedContractImpactFingerprint}'.`
        });
    }
    return {
        pair,
        taskDefinitionPath,
        implementationSummaryPath,
        taskText,
        summaryText,
        restoredTaskText,
        legacyBaseline,
        currentAttempt,
        currentAttemptId: options.taskCycleId,
        attemptBaseline: (0, baseline_planning_1.readAttemptRuntimeBaseline)(implementationSummaryPath, summaryText, options.taskCycleId),
        declaredTargetPaths: declaredTargets.explicitTargetPaths,
        contractImpact
    };
}
function previewTaskCycleRuntimeBaseline(repositoryRoot, options) {
    const context = resolveTaskBaselineContext(repositoryRoot, options);
    const { pair, taskDefinitionPath, implementationSummaryPath, taskText, summaryText, restoredTaskText, legacyBaseline, currentAttempt, currentAttemptId, attemptBaseline, declaredTargetPaths, contractImpact } = context;
    if (attemptBaseline !== null) {
        (0, repository_support_1.assertResumeIdentity)(attemptBaseline, options, implementationSummaryPath);
        if (options.resume !== true) {
            throw (0, errors_1.createUsageError)(`Current attempt '${currentAttemptId}' already records baseline '${attemptBaseline.baselineId}'.`, ["Use --resume with the exact stored identities; replacement is not supported."]);
        }
        return (0, repository_support_1.baselineResult)({
            taskDefinitionPath,
            implementationSummaryPath,
            action: "reused",
            baseline: attemptBaseline,
            intendedPaths: [],
            changedPaths: [],
            writeOutcome: "no-write",
            transactionId: null,
            evidenceGaps: []
        });
    }
    let baseline;
    let action;
    const evidenceGaps = [];
    if (legacyBaseline !== null) {
        if (options.resume !== true) {
            throw (0, errors_1.createUsageError)(`Task definition '${taskDefinitionPath}' records legacy baseline '${legacyBaseline.baselineId}'.`, ["Use --resume with exact attempt/readiness identities to migrate it without replacement."]);
        }
        (0, repository_support_1.assertResumeIdentity)(legacyBaseline, options, taskDefinitionPath);
        baseline = legacyBaseline;
        action = "migrated";
        if (baseline.capturedBy === null || baseline.capturedAt === null
            || baseline.workingTreeDigest === null || baseline.statusDigest === null) {
            evidenceGaps.push("Legacy baseline identity and observations were preserved exactly; actor/time and repository digest evidence absent from schema 1 was not invented.");
        }
    }
    else {
        if (options.resume === true) {
            throw (0, errors_1.createUsageError)(`Current attempt '${currentAttemptId}' has no baseline to resume.`, ["Capture the first attempt-owned baseline without --resume before implementation writes begin."]);
        }
        const capturedBy = (0, repository_support_1.requireActor)(options.capturedBy);
        const capturedAt = (0, repository_support_1.requireCaptureTime)(options.capturedAt, currentAttempt.openedAt);
        const adoptionSelections = (0, target_inspection_1.parseAdoptions)(options.adoptions ?? [], declaredTargetPaths);
        const inspectedTargets = declaredTargetPaths.map((targetPath) => (0, predecessor_evidence_1.inspectTarget)(pair.repositoryRoot, targetPath, adoptionSelections.manualAdoptions.get(targetPath) ?? null));
        const acceptedPredecessors = (0, predecessor_evidence_1.resolveAcceptedPredecessorTargets)({
            repositoryRoot: pair.repositoryRoot,
            currentTaskDefinitionPath: taskDefinitionPath,
            currentTaskText: taskText,
            targets: inspectedTargets,
            explicitlySelectedSources: adoptionSelections.acceptedRecoverySources
        });
        const targetEvidence = inspectedTargets.map((target) => {
            const acceptedPredecessor = acceptedPredecessors.get(target.path) ?? null;
            return acceptedPredecessor === null
                ? target
                : {
                    ...target,
                    preExistingClassification: "accepted-predecessor",
                    adoptionRationale: "",
                    acceptedPredecessor
                };
        });
        const sourceRevision = (0, repository_support_1.runGit)(pair.repositoryRoot, ["rev-parse", "--verify", "HEAD"]);
        const statusBytes = (0, repository_support_1.readBoundedGitStatus)(pair.repositoryRoot);
        if (sourceRevision === null || !contracts_1.SOURCE_REVISION_PATTERN.test(sourceRevision)) {
            throw (0, errors_1.createUsageError)("Task baseline capture requires a readable Git HEAD revision.", ["No files were written."]);
        }
        const provenance = (0, runtime_contract_1.getRuntimeProvenance)();
        const seed = {
            schemaVersion: 2,
            taskCycleId: options.taskCycleId,
            checkpointId: options.checkpointId,
            capturedAfterReadiness: true,
            capturedBeforeImplementationWrites: true,
            sourceRevision,
            repositoryDirtyState: targetEvidence.some((entry) => entry.dirty) || provenance.repositoryDirtyState === "dirty"
                ? "dirty"
                : "clean",
            cliRuntimeSource: provenance.runtimeSource,
            cliBuildIdentity: provenance.buildIdentity,
            capturedBy,
            capturedAt,
            workingTreeDigest: (0, repository_support_1.hashCanonical)({ sourceRevision, targets: targetEvidence }),
            statusDigest: `sha256:${(0, node_crypto_1.createHash)("sha256").update(statusBytes).digest("hex")}`,
            observationsComplete: true,
            contractImpactFingerprint: contractImpact.contractState === "valid"
                ? contractImpact.fingerprint
                : null,
            declaredTargets: targetEvidence
        };
        baseline = { ...seed, baselineId: (0, repository_support_1.hashCanonical)(seed) };
        action = "captured";
    }
    const nextSummaryText = (0, supplemental_baseline_1.insertAttemptRuntimeBaseline)(summaryText, currentAttemptId, baseline);
    const writes = action === "migrated"
        ? [
            { path: taskDefinitionPath, contents: restoredTaskText },
            { path: implementationSummaryPath, contents: nextSummaryText }
        ]
        : [{ path: implementationSummaryPath, contents: nextSummaryText }];
    const preconditions = [pair.task, pair.summary].flatMap((target) => [
        (0, mutation_preconditions_1.captureDestinationPresencePreconditionSync)(target),
        (0, mutation_preconditions_1.captureContentRevisionPreconditionSync)(target)
    ]);
    const snapshot = (0, repository_support_1.baselineResult)({
        taskDefinitionPath,
        implementationSummaryPath,
        action,
        baseline,
        intendedPaths: writes.map((write) => write.path),
        changedPaths: [],
        writeOutcome: "previewed",
        transactionId: null,
        evidenceGaps
    });
    contracts_1.baselinePlans.set(snapshot, {
        repositoryRoot: pair.repositoryRoot,
        writes,
        preconditions,
        snapshot
    });
    return snapshot;
}
function applyTaskCycleRuntimeBaseline(preview, options = {}) {
    const plan = contracts_1.baselinePlans.get(preview);
    if (plan === undefined) {
        throw (0, errors_1.createUsageError)("Task baseline apply requires the original in-process preview.", ["Refresh the preview."]);
    }
    if (plan.snapshot.baseline.capturedAt !== null) {
        (0, task_lifecycle_timestamps_1.revalidateObservedLifecycleTimestamp)(plan.snapshot.baseline.capturedAt, "captured_at", "Baseline captured_at");
    }
    const transaction = (0, repository_transaction_1.executeRepositoryTransactionSync)(plan.repositoryRoot, {
        writes: plan.writes,
        preconditions: plan.preconditions
    }, options.transaction);
    return (0, repository_support_1.baselineResult)({
        taskDefinitionPath: plan.snapshot.taskDefinitionPath,
        implementationSummaryPath: plan.snapshot.implementationSummaryPath,
        action: plan.snapshot.action,
        baseline: plan.snapshot.baseline,
        intendedPaths: plan.snapshot.intendedPaths,
        changedPaths: transaction.entries.slice(0, transaction.canonicalWrites).map((entry) => entry.path),
        writeOutcome: transaction.outcome,
        transactionId: transaction.transactionId,
        evidenceGaps: plan.snapshot.evidenceGaps
    });
}
function captureTaskCycleRuntimeBaseline(repositoryRoot, options) {
    const preview = previewTaskCycleRuntimeBaseline(repositoryRoot, options);
    return preview.writeOutcome === "no-write" ? preview : applyTaskCycleRuntimeBaseline(preview);
}
