"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.publishWorkingInPrMergeFinalization = publishWorkingInPrMergeFinalization;
exports.finalizeWorkflowStateForMerge = finalizeWorkflowStateForMerge;
const workflow_update_1 = require("../../comments/workflow-update");
const execution_ownership_1 = require("../execution-ownership");
const catalog_1 = require("../../i18n/catalog");
const types_1 = require("../../platform/ticket-tracker/types");
const types_2 = require("../../platform/workflow-state/types");
const constants_1 = require("../../worker/constants");
const types_3 = require("../../worker/types");
const publisher_events_1 = require("../../workflows/publisher-events");
const types_4 = require("../../workflows/types");
const log_text_1 = require("../log-text");
const constants_2 = require("../constants");
const effect_log_1 = require("./effect-log");
const event_hook_publication_1 = require("./event-hook-publication");
const effects_1 = require("./effects");
const followup_recommendation_state_1 = require("./followup-recommendation-state");
const merge_finalization_freshness_1 = require("./merge-finalization-freshness");
const needs_human_merge_support_1 = require("./needs-human-merge-support");
const pr_publication_1 = require("./pr-publication");
const results_1 = require("./results");
const issue_branch_target_1 = require("./issue-branch-target");
const default_issue_workspace_manager_1 = require("../../workspaces/default-issue-workspace-manager");
const unplanned_1 = require("./spawn-child/unplanned");
const transition_summary_1 = require("./transition-summary");
const transitions_1 = require("./transitions");
const terminal_followup_1 = require("./terminal-followup");
const workflow_closing_1 = require("./workflow-closing");
const workflow_template_root_1 = require("./workflow-template-root");
async function publishWorkingInPrMergeFinalization(input) {
    const workflowState = (0, needs_human_merge_support_1.resolveWorkflowStateForPublication)(input.issueComments, input.responseLanguage);
    const sourceSnapshot = resolveWorkingInPrSourceSnapshot(input.issue);
    const sourceBranchName = input.issue.sourceBranchName ??
        (0, default_issue_workspace_manager_1.resolveIssueBranchName)(input.context.config.branchPrefix, input.issue);
    let finalizedWorkflowState = workflowState === null
        ? null
        : finalizeWorkflowStateForMerge(workflowState, input.issue.baseTitle);
    const closingAudit = await runMergeFinalizationClosingAudit({
        ...input,
        workflowState,
        finalizedWorkflowState,
        sourceSnapshot,
        sourceBranchName,
    });
    if (closingAudit.kind === "summary") {
        return closingAudit.summary;
    }
    finalizedWorkflowState = closingAudit.workflowState;
    finalizedWorkflowState = await publishMergeFinalizationFollowups({
        context: input.context,
        issue: input.issue,
        workflowState: finalizedWorkflowState,
        responseLanguage: input.responseLanguage,
    });
    return publishMergeFinalizedSourceState({
        context: input.context,
        issue: input.issue,
        issueComments: input.issueComments,
        sourceSnapshot,
        workflowState: finalizedWorkflowState,
        responseLanguage: input.responseLanguage,
    });
}
function finalizeWorkflowStateForMerge(workflowState, issueBaseTitle) {
    const finalizedWorkflowState = { ...workflowState };
    delete finalizedWorkflowState.autoMergeState;
    if (workflowState.plan === null || workflowState.plan.steps.length === 0) {
        return finalizedWorkflowState;
    }
    return {
        ...finalizedWorkflowState,
        plan: {
            steps: workflowState.plan.steps.map((step) => ({
                ...step,
                result: resolveMergeFinalizedStepResult(step),
            })),
        },
        finalResult: resolveMergeFinalizedFinalResult(workflowState.finalResult, issueBaseTitle),
    };
}
async function runMergeFinalizationClosingAudit(input) {
    if (input.finalizedWorkflowState === null) {
        return { kind: "completed", workflowState: null };
    }
    const finalizedWorkflowState = input.finalizedWorkflowState;
    const workspaceResolution = await (0, merge_finalization_freshness_1.resolveMergeFinalizationClosingWorkspace)({
        context: input.context,
        issue: input.issue,
        workflowState: finalizedWorkflowState,
        sourceBranchName: input.sourceBranchName,
        pullRequest: input.pullRequest,
        responseLanguage: input.responseLanguage,
    });
    if (workspaceResolution.kind === "blocked") {
        return {
            kind: "summary",
            summary: await publishWorkingInPrMergeFinalizationFreshnessBlocked({
                context: input.context,
                issue: input.issue,
                logger: input.logger,
                pullRequest: input.pullRequest,
                responseLanguage: input.responseLanguage,
                reason: workspaceResolution.reason,
                error: workspaceResolution.error,
            }),
        };
    }
    const { freshnessExpectation, workspace } = workspaceResolution;
    let closingExecution;
    try {
        closingExecution = await runFreshWorkflowClosingWorker({
            ...input,
            finalizedWorkflowState,
            workspace,
            freshnessExpectation,
        });
    }
    catch (error) {
        if (error instanceof workflow_closing_1.WorkflowClosingFreshnessMismatchError) {
            return {
                kind: "summary",
                summary: await publishWorkingInPrMergeFinalizationFreshnessBlocked({
                    context: input.context,
                    issue: input.issue,
                    logger: input.logger,
                    pullRequest: input.pullRequest,
                    responseLanguage: input.responseLanguage,
                    reason: `workflow_closing_freshness_mismatch:${error.expectedCommitKind}:${error.expectedCommitOid}:${error.workspaceHeadCommitOid}`,
                    error,
                }),
            };
        }
        throw error;
    }
    if (closingExecution.workerOutcome !== constants_1.WORKER_OUTCOMES.proceed ||
        closingExecution.continuation !== null) {
        return {
            kind: "summary",
            summary: await publishWorkingInPrClosingTransition({
                context: input.context,
                issue: input.issue,
                logger: input.logger,
                workspace,
                sourceSnapshot: input.sourceSnapshot,
                closingExecution,
                previousConsecutiveAiRuns: input.workflowState?.consecutiveAiRuns ?? 0,
            }),
        };
    }
    return {
        kind: "completed",
        workflowState: (0, followup_recommendation_state_1.applyWorkflowClosingFollowupRecommendation)({
            workflowState: closingExecution.workflowState,
            recommendation: closingExecution.followupRecommendation,
            recommendationSource: (0, followup_recommendation_state_1.buildWorkflowClosingFollowupRecommendationSource)({
                workerExecution: closingExecution,
                expectedCommitOid: freshnessExpectation.expectedCommitOid,
                expectedCommitKind: freshnessExpectation.expectedCommitKind,
                ...(freshnessExpectation.pullRequestNumber !== undefined
                    ? { pullRequestNumber: freshnessExpectation.pullRequestNumber }
                    : {}),
                ...(freshnessExpectation.pullRequestUrl !== undefined
                    ? { pullRequestUrl: freshnessExpectation.pullRequestUrl }
                    : {}),
            }),
        }),
    };
}
async function runFreshWorkflowClosingWorker(input) {
    return await (0, workflow_closing_1.runWorkflowClosingWorker)({
        context: input.context,
        logger: input.logger,
        workspace: input.workspace,
        previousConsecutiveAiRuns: input.workflowState?.consecutiveAiRuns ?? 0,
        latestIssue: ensureTrackerIssueWithSnapshot(input.issue, resolveWorkingInPrSourceSnapshot(input.issue)),
        comments: input.issueComments,
        workerExecution: buildMergeFinalizationClosingSeed({
            context: input.context,
            issue: input.issue,
            workflowState: input.finalizedWorkflowState,
            responseLanguage: input.responseLanguage,
        }),
        freshnessExpectation: input.freshnessExpectation,
    });
}
async function publishMergeFinalizationFollowups(input) {
    const hadFollowupRequestLabel = (0, terminal_followup_1.hasFollowupRequestLabel)(input.context, input.issue);
    const followupOutcome = await (0, terminal_followup_1.publishSourceFollowupIssueIfNeeded)({
        context: input.context,
        workflowLabels: input.context.config.ticketTracker.workflowLabels,
        sourceIssue: input.issue,
        sourceWorkflowState: input.workflowState,
        responseLanguage: input.responseLanguage,
        clearRequestLabelOnSuccess: false,
        publishFeedback: true,
    });
    if (hadFollowupRequestLabel &&
        (followupOutcome.result?.kind === "created" ||
            followupOutcome.result?.kind === "reused") &&
        followupOutcome.workflowState !== null) {
        await (0, terminal_followup_1.publishFollowupSourceWorkflowState)({
            context: input.context,
            sourceIssue: input.issue,
            workflowState: followupOutcome.workflowState,
            responseLanguage: input.responseLanguage,
            clearRequestLabel: true,
        });
    }
    return followupOutcome.workflowState;
}
async function publishMergeFinalizedSourceState(input) {
    const trackerTitle = (0, effects_1.resolveRenderedTitleIfChanged)({
        issue: input.issue,
        workflowState: input.workflowState,
        locale: input.responseLanguage,
        surface: "issue",
        enabled: input.context.config.ticketTracker.showStepProgressInTitles === true,
    });
    const plan = (0, pr_publication_1.buildWorkingInPrMergeFinalizationPublicationPlan)({
        workflowLabels: input.context.config.ticketTracker.workflowLabels,
        responseLanguage: input.responseLanguage,
        sourceIssue: input.issue,
        sourceSnapshot: input.sourceSnapshot,
        sourceWorkflowState: input.workflowState,
        sourceNeedsHumanReason: (0, workflow_update_1.findLatestNeedsHumanReason)(input.issueComments),
        ...(trackerTitle !== null ? { trackerTitle } : {}),
    });
    if (plan.kind !== "working_in_pr_merge_finalization") {
        throw new Error("Expected a working-in-PR merge finalization publication plan.");
    }
    const publication = await (0, event_hook_publication_1.publishRunWorkflowWithEventHooks)({
        context: input.context,
        request: plan.sourceIssueRequest,
    });
    if (publication.targetClosed) {
        input.issue.isOpen = false;
    }
    return null;
}
async function publishWorkingInPrMergeFinalizationFreshnessBlocked(input) {
    const summary = buildWorkingInPrFinalizationFreshnessBlockedSummary(input.responseLanguage);
    const next = buildWorkingInPrFinalizationFreshnessBlockedNextMessage(input.responseLanguage);
    const sourceIssue = ensureTrackerIssueWithSnapshot(input.issue, resolveWorkingInPrSourceSnapshot(input.issue));
    const publication = await (0, needs_human_merge_support_1.publishControlPlaneNeedsHumanUpdate)({
        context: input.context,
        issue: sourceIssue,
        responseLanguage: input.responseLanguage,
        summary,
        next,
        needsHumanReason: publisher_events_1.WORKFLOW_NEEDS_HUMAN_REASONS.systemError,
        eventHookOrigin: "control_plane_error_handoff",
        eventHookLogger: input.logger,
    });
    await (0, effect_log_1.appendEffectFailureLog)(input.logger, [
        (0, log_text_1.issueLogField)("effect", "finalize_issue_after_pr_merge"),
        (0, log_text_1.issueLogField)("pr", input.pullRequest.url),
        (0, log_text_1.issueLogField)("note", "workspace_freshness_not_verified"),
        (0, log_text_1.issueLogField)("reason", input.reason),
        ...(input.error === undefined
            ? []
            : [(0, results_1.renderFailureDetails)(input.error, input.logger.locale)]),
    ]);
    return (0, results_1.buildRunCliSummary)({
        issue: sourceIssue,
        outcome: constants_2.RUN_ISSUE_OUTCOMES.queuedHuman,
        responseLanguage: input.responseLanguage,
        summary,
        commentUrl: publication.visibleUpdateComment?.url ?? null,
        prUrl: input.pullRequest.url,
        nextStep: next,
    });
}
async function publishWorkingInPrClosingTransition(input) {
    const sourceIssue = ensureTrackerIssueWithSnapshot(input.issue, input.sourceSnapshot);
    const claimedIssue = buildMergeFinalizationClaimedIssue({
        issue: sourceIssue,
        sourceSnapshot: input.sourceSnapshot,
        previousConsecutiveAiRuns: input.previousConsecutiveAiRuns,
        context: input.context,
    });
    if (input.closingExecution.continuation?.strategy === "spawn_child_issue") {
        return (0, unplanned_1.publishSpawnChildContinuation)({
            context: input.context,
            claimedIssue,
            logger: input.logger,
            workflowLabels: input.context.config.ticketTracker.workflowLabels,
            workspace: input.workspace,
            workerExecution: input.closingExecution,
        });
    }
    const transitionState = (0, transitions_1.buildSuccessfulTransitionState)(input.context.config, claimedIssue, input.closingExecution);
    return (0, transition_summary_1.publishTransitionSummary)({
        repoRoot: (0, workflow_template_root_1.getWorkflowTemplateRepoRoot)(input.context),
        config: input.context.config,
        currentUserLogin: input.context.currentUserLogin,
        repositoryHost: input.context.repositoryHost,
        ticketTracker: input.context.ticketTracker,
        issueId: sourceIssue.id,
        transitionState,
        logger: input.logger,
        workflowLabels: input.context.config.ticketTracker.workflowLabels,
        fromStatus: input.sourceSnapshot.status,
        resolvedFacts: input.closingExecution.facts,
        latestIssue: sourceIssue,
        worker: input.context.worker,
        ...(input.context.logHomeDirectory !== undefined
            ? { homeDirectory: input.context.logHomeDirectory }
            : {}),
    });
}
function buildMergeFinalizationClaimedIssue(input) {
    return {
        originalIssue: input.issue,
        aiReadySnapshot: {
            status: types_2.WORKFLOW_STATUSES.aiReady,
            rules: [...input.sourceSnapshot.rules],
        },
        aiRunningSnapshot: input.sourceSnapshot,
        executionOwnership: (0, execution_ownership_1.createExecutionOwnership)({
            workerIdentity: input.context.workerIdentity,
            pollIntervalSec: input.context.config.pollIntervalSec,
        }),
        previousConsecutiveAiRuns: input.previousConsecutiveAiRuns,
    };
}
function resolveWorkingInPrSourceSnapshot(issue) {
    return (0, types_1.hasTrackerWorkflowState)(issue)
        ? issue.workflowState
        : {
            status: types_2.WORKFLOW_STATUSES.aiWorkingInPr,
            rules: [],
        };
}
function ensureTrackerIssueWithSnapshot(issue, snapshot) {
    return (0, types_1.hasTrackerWorkflowState)(issue)
        ? issue
        : {
            ...issue,
            workflowState: snapshot,
        };
}
function buildMergeFinalizationClosingSeed(input) {
    const baseBranch = (0, issue_branch_target_1.resolveIssueRunBaseBranch)(input.workflowState);
    return {
        issue: ensureTrackerIssueWithSnapshot(input.issue, {
            status: types_2.WORKFLOW_STATUSES.aiWorkingInPr,
            rules: [],
        }),
        workerId: "control-plane",
        workerName: "control-plane",
        authProfileId: "control-plane",
        authProfileKind: "control-plane",
        workspaceHeadCommitOidBeforeRun: "",
        runMode: types_3.WORKER_RUN_MODES.workflowExecute,
        workerOutcome: constants_1.WORKER_OUTCOMES.proceed,
        result: (0, types_4.buildWorkflowResultFieldsWithDefaults)({
            resultSummary: `Completed during PR merge finalization: ${input.issue.baseTitle}`,
            evidence: [
                `PR merge finalization completed for ${input.issue.displayId}.`,
            ],
        }),
        commitMessage: null,
        consecutiveAiRuns: input.workflowState.consecutiveAiRuns,
        responseLanguage: input.responseLanguage,
        facts: (0, results_1.buildRoutingResolution)(false, (0, results_1.filterPullRequestByBase)(null, baseBranch)).facts,
        branchName: input.issue.sourceBranchName ??
            (0, default_issue_workspace_manager_1.resolveIssueBranchName)(input.context.config.branchPrefix, input.issue),
        pullRequestUrl: null,
        scannedInputCursor: input.workflowState.lastScannedCommentCursor ?? null,
        workflowTemplateName: null,
        workflowState: input.workflowState,
        plannedIssueTitle: null,
        mergeContext: null,
        planningIntent: null,
        workflowStartApproval: null,
        startedWithPlanningIntent: null,
        startedWithWorkflowStartApprovalIntent: null,
        continuation: null,
        needsHumanReason: null,
        incrementsConsecutiveAiRuns: true,
        recordsRunOutcome: true,
    };
}
function resolveMergeFinalizedFinalResult(finalResult, issueBaseTitle) {
    const mergeEvidence = `Merge integration finalization completed for ${issueBaseTitle}.`;
    if (finalResult?.outcome === constants_1.WORKER_OUTCOMES.proceed) {
        const evidence = finalResult.evidence ?? [];
        return (0, types_4.buildWorkflowFinalResultWithDefaults)({
            outcome: constants_1.WORKER_OUTCOMES.proceed,
            resultSummary: finalResult.resultSummary,
            evidence: evidence.includes(mergeEvidence)
                ? evidence
                : [...evidence, mergeEvidence],
            humanComment: finalResult.humanComment ?? null,
        });
    }
    return (0, types_4.buildWorkflowFinalResultWithDefaults)({
        outcome: constants_1.WORKER_OUTCOMES.proceed,
        resultSummary: `Completed during PR merge finalization: ${issueBaseTitle}`,
        evidence: [mergeEvidence],
    });
}
function resolveMergeFinalizedStepResult(step) {
    if (step.result?.outcome === constants_1.WORKER_OUTCOMES.proceed) {
        return step.result;
    }
    return buildCompletedWorkflowResult(step);
}
function buildCompletedWorkflowResult(step) {
    return (0, types_4.buildWorkflowResultWithDefaults)({
        outcome: constants_1.WORKER_OUTCOMES.proceed,
        resultSummary: `Completed during PR merge finalization: ${step.objective}`,
        evidence: [
            `PR merge finalization marked this step complete: ${step.title}`,
            ...renderPreviousStepResultEvidence(step.result),
        ],
    });
}
function renderPreviousStepResultEvidence(result) {
    if (result === null) {
        return [];
    }
    const evidence = [
        `Previous result before PR merge finalization: ${result.outcome} - ${result.resultSummary}`,
        ...(result.evidence ?? []).map((entry) => `Previous evidence before PR merge finalization: ${entry}`),
    ];
    const humanComment = result.humanComment?.trim();
    return humanComment
        ? [
            ...evidence,
            `Previous human comment before PR merge finalization: ${humanComment}`,
        ]
        : evidence;
}
function buildWorkingInPrFinalizationFreshnessBlockedSummary(responseLanguage) {
    return (0, catalog_1.translate)(responseLanguage, "run.workingInPr.finalizationFreshnessBlocked.summary");
}
function buildWorkingInPrFinalizationFreshnessBlockedNextMessage(responseLanguage) {
    return (0, catalog_1.translate)(responseLanguage, "run.workingInPr.finalizationFreshnessBlocked.next");
}
