"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTaskAttemptSupersedeCommand = createTaskAttemptSupersedeCommand;
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const task_attempts_1 = require("../../../lib/planning/task-attempts");
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
const global_format_1 = require("../global-format");
async function createTaskAttemptSupersedeCommand() {
    const { Command } = await import("commander");
    const command = new Command("attempt-supersede");
    command
        .description("Preview or atomically supersede one stale-authorization baseline-only attempt without discarding its attribution evidence.")
        .requiredOption("--task-definition <path>", "Repository-relative canonical task-definition.md path.")
        .requiredOption("--attempt-id <identity>", "Exact open current attempt identity to supersede.")
        .requiredOption("--task-revision <revision>", "Exact current 64-character task revision observed before supersession.")
        .requiredOption("--recorded-by <actor>", "Non-empty attempt-supersession actor.")
        .requiredOption("--recorded-at <timestamp>", "ISO-8601 attempt-supersession time with explicit timezone.")
        .requiredOption("--reason <text>", "Non-empty reason for the authorized planning-contract revision.")
        .option("--dry-run", "Preview exact pair preconditions and supersession writes without mutation; omit to apply.")
        .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.");
        const repository = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const options = commandInstance.opts();
        let result;
        try {
            const preview = (0, task_attempts_1.previewTaskAttemptSupersedeSync)({
                repositoryRoot: repository.root,
                taskDefinitionPath: options.taskDefinition,
                attemptId: options.attemptId,
                taskRevision: options.taskRevision,
                recordedBy: options.recordedBy,
                recordedAt: options.recordedAt,
                reason: options.reason
            });
            result = options.dryRun === true || preview.writeOutcome === "no-write"
                ? preview
                : (0, task_attempts_1.applyTaskAttemptSupersedeSync)(preview);
        }
        catch (error) {
            throw normalizeAttemptSupersedeError(error, options.taskDefinition);
        }
        if (!["previewed", "committed", "no-write"].includes(result.writeOutcome)) {
            throw createAttemptSupersedeOutcomeError(result);
        }
        (0, output_1.emitSuccess)({
            command: "task attempt-supersede",
            format,
            text: renderText(result),
            data: {
                ...result,
                repositoryRoot: repository.root,
                detectionSource: repository.detectionSource,
                nextAction: result.writeOutcome === "previewed"
                    ? "Inspect the exact pair revisions, baseline identity, intended paths, and transaction preconditions, then rerun without --dry-run."
                    : "Run a fresh readiness review, authorize that current review, open a new attempt identity, and capture a new expanded baseline."
            }
        });
    });
    return command;
}
function normalizeAttemptSupersedeError(error, taskDefinitionPath) {
    if (error instanceof errors_1.RuntimeError)
        return error;
    if (error instanceof task_attempts_1.TaskAttemptSupersedeError || error instanceof task_attempts_1.TaskAttemptOpenError) {
        const normalizedCode = error.code.replace(/-/g, "_").toUpperCase();
        const code = `TASK_ATTEMPT_SUPERSEDE_${normalizedCode}`;
        const exitCode = error.code === "stale-preview" || error.code === "stale-revision"
            ? errors_1.RuntimeExitCode.STALE_EVIDENCE
            : error.code === "git-inspection-unavailable"
                ? errors_1.RuntimeExitCode.UNAVAILABLE_DEPENDENCY
                : error.code === "attempt-conflict"
                    || error.code === "baseline-required"
                    || error.code === "implementation-delta"
                    || error.code === "evidence-bearing-attempt"
                    || error.code === "pair-invalid"
                    ? errors_1.RuntimeExitCode.INVALID_CONFIG
                    : errors_1.RuntimeExitCode.USAGE;
        return new errors_1.RuntimeError({
            message: "Task attempt-supersede was rejected.",
            code,
            exitCode,
            writeOutcome: "no-writes",
            details: [
                error.message,
                "No task-definition, implementation-summary, baseline, attempt, or readiness evidence was written.",
                error.code === "git-inspection-unavailable"
                    ? "Restore Git inspection in the current repository environment, then retry the exact supersession request; no implementation delta was inferred."
                    : "Refresh the selected pair and continue only when the exact current attempt is baseline-only and all declared targets remain unchanged from its attribution boundary."
            ],
            findings: [{
                    code,
                    severity: "error",
                    message: error.message,
                    path: taskDefinitionPath,
                    noWriteBoundary: "Rejected attempt-supersede transitions do not mutate the selected task pair."
                }],
            ...(error.code === "git-inspection-unavailable"
                ? {
                    recoveryActions: [(0, errors_1.createNonCallableRecoveryAction)({
                            id: "recovery.task-attempt-supersede.restore-git-inspection",
                            command: "task attempt-supersede",
                            explanation: "Restore an inspectable Git executable and repository state, then retry the exact revision-bound request.",
                            reason: "The original attempt, revision, actor, time, and reason cannot be safely reconstructed by the failure boundary."
                        })]
                }
                : {})
        });
    }
    throw error;
}
function createAttemptSupersedeOutcomeError(result) {
    const details = [
        `writeOutcome: ${result.writeOutcome}`,
        `intendedPaths: ${JSON.stringify(result.intendedPaths)}`,
        `changedPaths: ${JSON.stringify(result.changedPaths)}`,
        `conflicts: ${JSON.stringify(result.conflicts)}`,
        `recoveryPath: ${result.recoveryPath ?? "null"}`,
        `failure: ${result.failure ?? "null"}`
    ];
    if (result.writeOutcome === "conflict") {
        return new errors_1.RuntimeError({
            message: "Task attempt-supersede preview is stale or conflicted.",
            code: "TASK_ATTEMPT_SUPERSEDE_CONFLICT",
            exitCode: errors_1.RuntimeExitCode.CONCURRENCY_CONFLICT,
            writeOutcome: "no-writes",
            details,
            recoveryActions: [(0, errors_1.createNonCallableRecoveryAction)({
                    id: "recovery.refresh-task-attempt-supersede-preview",
                    command: "task attempt-supersede",
                    explanation: "Refresh both task-pair revisions and preview the exact supersession transition again.",
                    reason: "The original attempt identity, task revision, actor, time, and reason must be supplied again."
                })]
        });
    }
    if (result.writeOutcome === "incomplete") {
        return new errors_1.RuntimeError({
            message: "Task attempt-supersede stopped with incomplete repository state.",
            code: "TASK_ATTEMPT_SUPERSEDE_INCOMPLETE",
            exitCode: errors_1.RuntimeExitCode.PARTIAL_MUTATION,
            writeOutcome: "partial",
            details,
            recoveryActions: [(0, errors_1.createNonCallableRecoveryAction)({
                    id: "recovery.inspect-task-attempt-supersede-transaction",
                    explanation: "Inspect retained transaction evidence before retrying or repairing the task pair.",
                    reason: result.recoveryPath ?? "The retained transaction path was unavailable."
                })]
        });
    }
    return new errors_1.RuntimeError({
        message: "Task attempt-supersede produced no canonical result.",
        code: "TASK_ATTEMPT_SUPERSEDE_NO_WRITE",
        exitCode: errors_1.RuntimeExitCode.ERROR,
        details
    });
}
function renderText(result) {
    return [
        "Task implementation attempt supersession",
        "",
        `Task definition: ${result.taskDefinitionPath}`,
        `Implementation summary: ${result.implementationSummaryPath}`,
        `Prior attempt ID: ${result.priorAttemptId}`,
        `Supersession state: ${result.supersessionState}`,
        `Baseline ID: ${result.baselineId}`,
        `Bound task revision: ${result.boundTaskRevision}`,
        `Next task revision: ${result.nextTaskRevision}`,
        `Next implementation-summary revision: ${result.nextImplementationSummaryRevision}`,
        `Recorded by: ${result.recordedBy}`,
        `Recorded at: ${result.recordedAt}`,
        `Reason: ${result.reason}`,
        `Idempotent replay: ${result.idempotent ? "yes" : "no"}`,
        `Write outcome: ${result.writeOutcome}`,
        `Changed paths: ${result.changedPaths.length}`
    ].join("\n");
}
