"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runWorkflowPlanReviewLoop = runWorkflowPlanReviewLoop;
exports.resolveWorkflowPlanReviewCandidate = resolveWorkflowPlanReviewCandidate;
exports.resolvePlanReviewRevisionIntent = resolvePlanReviewRevisionIntent;
const types_1 = require("../../worker/types");
const state_1 = require("../../workflows/state");
async function runWorkflowPlanReviewLoop(input) {
    let currentStage = input.initialStage;
    let revisionsUsed = 0;
    let carriedFields = readCarriedPlanningFields(currentStage.workerResult.launchResult.decision);
    while (true) {
        const candidate = resolveWorkflowPlanReviewCandidate({
            execution: currentStage.execution,
            workerResult: currentStage.workerResult,
            responseLanguage: input.responseLanguage,
        });
        if (candidate === null) {
            return {
                kind: "continue",
                value: input.applyAcceptedStage({
                    stage: currentStage,
                    carriedFields,
                }),
            };
        }
        const planningIntent = currentStage.execution.planningIntent ?? "new_plan";
        const reviewResult = await input.runReview({
            candidate,
            planningIntent,
            priorWorkerDurationMs: currentStage.execution.workerDurationMs +
                (currentStage.workerResult.workerDurationMs ?? 0),
        });
        if (reviewResult.kind === "state") {
            return reviewResult;
        }
        const review = reviewResult.value.review;
        const durationThroughReview = currentStage.execution.workerDurationMs +
            (currentStage.workerResult.workerDurationMs ?? 0) +
            reviewResult.value.workerDurationMs;
        if (review.action === types_1.WORKER_WORKFLOW_PLAN_REVIEW_ACTIONS.usePlan) {
            return {
                kind: "continue",
                value: input.applyAcceptedStage({
                    stage: withAdditionalExecutionDuration(currentStage, reviewResult.value.workerDurationMs),
                    carriedFields,
                }),
            };
        }
        if (review.action === types_1.WORKER_WORKFLOW_PLAN_REVIEW_ACTIONS.blockExecution) {
            return {
                kind: "state",
                state: input.buildBlockedState({
                    reason: "block_execution",
                    review,
                    candidate,
                    currentStage,
                    carriedFields,
                    durationThroughReview,
                    revisionsUsed,
                }),
            };
        }
        if (revisionsUsed >= input.maxRevisions &&
            review.findings.some((finding) => finding.severity === "blocker")) {
            return {
                kind: "state",
                state: input.buildBlockedState({
                    reason: "revision_budget_exhausted_with_blocker",
                    review,
                    candidate,
                    currentStage,
                    carriedFields,
                    durationThroughReview,
                    revisionsUsed,
                }),
            };
        }
        if (revisionsUsed >= input.maxRevisions) {
            return {
                kind: "continue",
                value: input.applyAcceptedStage({
                    stage: withAdditionalExecutionDuration(currentStage, reviewResult.value.workerDurationMs),
                    carriedFields,
                }),
            };
        }
        const revisionStage = await input.runRevision({
            currentStage,
            candidate,
            review,
            reviewRound: revisionsUsed + 1,
            planningIntent,
            workerDurationMs: durationThroughReview,
        });
        if (revisionStage.kind === "state") {
            return revisionStage;
        }
        revisionsUsed += 1;
        carriedFields = updateCarriedPlanningFields(carriedFields, revisionStage.value.workerResult.launchResult.decision);
        currentStage = revisionStage.value;
    }
}
function resolveWorkflowPlanReviewCandidate(input) {
    const resolvedWorkflow = (0, state_1.resolveWorkerExecutionWorkflow)({
        workflow: input.execution.workflow,
        workflowTemplateName: input.execution.workflowTemplateName,
        workflowState: input.execution.workflowState,
    }, input.workerResult.launchResult.decision, input.responseLanguage);
    const workflowState = resolvedWorkflow.workflowState;
    const plan = workflowState?.plan ?? null;
    if (workflowState === null || plan === null) {
        return null;
    }
    return {
        workflowTemplateName: resolvedWorkflow.workflowTemplateName,
        workflowState,
        plan,
    };
}
function resolvePlanReviewRevisionIntent(planningIntent) {
    return planningIntent === "replan" ? "replan" : "revise_plan";
}
function readCarriedPlanningFields(decision) {
    return {
        ...(decision.issueTitle === undefined
            ? {}
            : { issueTitle: decision.issueTitle }),
    };
}
function updateCarriedPlanningFields(current, decision) {
    return {
        ...current,
        ...(decision.issueTitle === undefined
            ? {}
            : { issueTitle: decision.issueTitle }),
    };
}
function withAdditionalExecutionDuration(stage, workerDurationMs) {
    return {
        ...stage,
        execution: {
            ...stage.execution,
            workerDurationMs: stage.execution.workerDurationMs + workerDurationMs,
        },
    };
}
