"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.claimWorkflowExecution = claimWorkflowExecution;
exports.buildClaimedExecutionWorkflowState = buildClaimedExecutionWorkflowState;
exports.confirmClaimedExecutionOwnership = confirmClaimedExecutionOwnership;
const canonical_workflow_state_1 = require("../../comments/canonical-workflow-state");
const workflow_labels_1 = require("../../platform/ticket-tracker/workflow-labels");
const types_1 = require("../../platform/workflow-state/types");
const publisher_shared_1 = require("../../workflows/publisher-shared");
const persisted_state_1 = require("../../workflows/state/persisted-state");
const visible_update_builders_1 = require("../../workflows/visible-update-builders");
const workflow_state_read_support_1 = require("../../workflows/workflow-state-read-support");
const execution_ownership_1 = require("../execution-ownership");
const log_text_1 = require("../log-text");
const publisher_factory_1 = require("./publisher-factory");
const shared_1 = require("./shared");
const start_approval_review_1 = require("./start-approval-review");
async function claimWorkflowExecution(input) {
    const aiReadySnapshot = (0, shared_1.cloneWorkflowStateSnapshot)(input.executable.snapshot, types_1.WORKFLOW_STATUSES.aiReady);
    const aiRunningSnapshot = (0, shared_1.cloneWorkflowStateSnapshot)(input.executable.snapshot, types_1.WORKFLOW_STATUSES.aiRunning);
    const claimedIssue = {
        originalIssue: input.executable.issue,
        aiReadySnapshot,
        aiRunningSnapshot,
        executionOwnership: input.executionOwnership,
        previousConsecutiveAiRuns: input.previousConsecutiveAiRuns,
    };
    const workflowState = buildClaimedExecutionWorkflowState({
        responseLanguage: input.responseLanguage,
        comments: input.comments,
        workflowState: input.workflowState,
        planningIntent: input.planningIntent,
        currentConsecutiveAiRuns: input.currentConsecutiveAiRuns,
        lastScannedCommentCursor: input.lastScannedCommentCursor,
        claimedIssue,
    });
    const shouldPublishRunningProjection = input.executable.snapshot.status !== types_1.WORKFLOW_STATUSES.aiRunning;
    if (shouldPublishRunningProjection) {
        const publisher = (0, publisher_factory_1.createRunWorkflowPublisher)(input.context);
        const auxiliaryManagedLabels = resolveClaimAuxiliaryManagedLabels({
            workflowLabels: input.context.config.ticketTracker.workflowLabels,
            originalWorkflowState: input.executable.issue.workflowState,
            workflowState: input.workflowState,
        });
        await publisher.publishWorkflow({
            target: {
                kind: "existing_issue",
                issueId: input.executable.issue.id,
                preloadedIssue: input.executable.issue,
            },
            workflowState: null,
            workflowProjection: {
                previous: input.executable.issue.workflowState,
                next: aiRunningSnapshot,
                ...(auxiliaryManagedLabels !== null ? { auxiliaryManagedLabels } : {}),
            },
            visibleUpdate: input.executable.publishStartVisibleUpdate
                ? (0, visible_update_builders_1.buildWorkflowStartedVisibleUpdate)({
                    language: input.logger.locale,
                })
                : null,
            commentCursorPolicy: {
                mode: publisher_shared_1.WORKFLOW_COMMENT_CURSOR_POLICY_MODES.preserve,
            },
            responseLanguage: input.responseLanguage,
        });
    }
    if (workflowState !== null) {
        const publisher = (0, publisher_factory_1.createRunWorkflowPublisher)(input.context);
        await publisher.publishWorkflow({
            target: {
                kind: "existing_issue",
                issueId: input.executable.issue.id,
                preloadedIssue: input.executable.issue,
            },
            workflowState,
            commentCursorPolicy: {
                mode: publisher_shared_1.WORKFLOW_COMMENT_CURSOR_POLICY_MODES.preserve,
            },
            responseLanguage: input.responseLanguage,
        });
    }
    await input.logger.appendSection((0, log_text_1.issueLogSection)("claimIssue"), [
        (0, log_text_1.issueLogField)("workflowAfterClaim", types_1.WORKFLOW_STATUSES.aiRunning),
        `workerId: ${input.executionOwnership.workerId}`,
        `runId: ${input.executionOwnership.runId}`,
        `expiresAt: ${input.executionOwnership.expiresAt}`,
    ].join("\n"));
    return claimedIssue;
}
function resolveClaimAuxiliaryManagedLabels(input) {
    if (!(0, persisted_state_1.isHumanInputResumeProjection)({
        snapshot: input.originalWorkflowState,
        workflowState: input.workflowState,
    })) {
        return null;
    }
    const previous = (0, workflow_labels_1.resolveNeedsHumanReasonLabelNames)(input.workflowLabels, input.workflowState?.needsHumanReason ?? null);
    return previous.length > 0 ? { previous, next: [] } : null;
}
function buildClaimedExecutionWorkflowState(input) {
    if (input.workflowState === null) {
        return null;
    }
    const pendingPlanningIntent = input.planningIntent === null || input.planningIntent === "new_plan"
        ? input.workflowState.pendingPlanningIntent
        : input.planningIntent;
    const shouldPersistPendingPlanningIntent = pendingPlanningIntent !== undefined;
    const shouldPreserveCanonicalPlanDuringClaim = (0, start_approval_review_1.isRevisePlanContext)(input.comments) && shouldPersistPendingPlanningIntent;
    const claimedWorkflowState = shouldPreserveCanonicalPlanDuringClaim && input.workflowState.plan === null
        ? (resolveExistingCanonicalWorkflowState(input.comments, input.responseLanguage) ?? input.workflowState)
        : input.workflowState;
    const workflowStateToPersist = pendingPlanningIntent === undefined
        ? claimedWorkflowState
        : {
            ...claimedWorkflowState,
            pendingPlanningIntent,
        };
    const shouldResetHumanResumeState = (0, persisted_state_1.isHumanInputResumeProjection)({
        snapshot: input.claimedIssue.originalIssue.workflowState,
        workflowState: workflowStateToPersist,
    });
    const resumableWorkflowState = shouldResetHumanResumeState
        ? (0, persisted_state_1.resetHumanInputResumeState)(workflowStateToPersist)
        : workflowStateToPersist;
    return (0, execution_ownership_1.withExecutionOwnership)({
        ...resumableWorkflowState,
        consecutiveAiRuns: shouldResetHumanResumeState
            ? resumableWorkflowState.consecutiveAiRuns
            : input.currentConsecutiveAiRuns,
        totalAiRunHours: shouldResetHumanResumeState
            ? resumableWorkflowState.totalAiRunHours
            : (0, shared_1.resolveCurrentTotalAiRunHours)(input.comments, input.claimedIssue.originalIssue),
        lastScannedCommentCursor: input.lastScannedCommentCursor,
    }, input.claimedIssue.executionOwnership);
}
async function confirmClaimedExecutionOwnership(input) {
    const [latestIssue, workflowState] = await Promise.all([
        input.context.freshTicketTracker.getIssue(input.issueId),
        (0, workflow_state_read_support_1.resolvePersistedIssueWorkflowState)(input.context.freshTicketTracker, input.issueId),
    ]);
    return (latestIssue.workflowState.status === types_1.WORKFLOW_STATUSES.aiRunning &&
        (0, shared_1.matchesClaimedExecutionOwnership)({
            originalIssue: input.claimedIssue.originalIssue,
            latestIssue,
            currentExecutionOwnership: workflowState?.executionOwnership,
            expectedExecutionOwnership: input.claimedIssue.executionOwnership,
        }));
}
function resolveExistingCanonicalWorkflowState(comments, responseLanguage) {
    const resolution = (0, canonical_workflow_state_1.resolveCanonicalWorkflowStateComment)(comments, responseLanguage);
    if (resolution.kind !== "found") {
        return null;
    }
    return resolution.workflowState;
}
