"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveCanonicalWorkflowStateComment = resolveCanonicalWorkflowStateComment;
exports.summarizeCanonicalWorkflowState = summarizeCanonicalWorkflowState;
exports.selectLatestResult = selectLatestResult;
exports.selectActionRequiredLines = selectActionRequiredLines;
exports.selectCurrentStepResult = selectCurrentStepResult;
const catalog_1 = require("../../i18n/catalog");
const display_time_1 = require("../../i18n/display-time");
const approval_instructions_1 = require("../../workflows/approval-instructions");
const scheduled_run_1 = require("../../workflows/scheduled-run");
const template_bindings_1 = require("../../workflows/template-bindings");
const defs_1 = require("./defs");
const helpers_1 = require("./helpers");
const parse_1 = require("./parse");
const results_1 = require("./results");
const scheduling_1 = require("./scheduling");
const start_approval_1 = require("./start-approval");
const tree_1 = require("./tree");
function resolveCanonicalWorkflowStateComment(comments, locale = catalog_1.DEFAULT_APP_LOCALE) {
    for (const comment of [...comments].reverse()) {
        if (!(0, parse_1.isCanonicalWorkflowStateComment)(comment.body)) {
            continue;
        }
        const workflowState = (0, parse_1.parseCanonicalWorkflowStateComment)(comment.body);
        if (workflowState === null) {
            return {
                kind: "invalid",
                comment,
                summary: (0, catalog_1.translate)(locale, "workflow.runContext.canonical.invalid"),
            };
        }
        return {
            kind: "found",
            comment,
            workflowState,
        };
    }
    return { kind: "missing" };
}
function summarizeCanonicalWorkflowState(workflowState, locale = catalog_1.DEFAULT_APP_LOCALE, displayTimeZone = "UTC", issueId) {
    const latestResult = selectLatestResult(workflowState);
    return {
        currentStep: renderCurrentStepSummary(workflowState, locale),
        next: renderNextSummary(workflowState, locale, displayTimeZone, issueId),
        workflowTemplateName: resolveWorkflowTemplateName(workflowState),
        resultSummary: latestResult?.resultSummary ?? null,
    };
}
function resolveWorkflowTemplateName(workflowState) {
    return (0, template_bindings_1.getWorkflowTemplateName)((0, template_bindings_1.getActiveWorkflowTemplateBinding)(workflowState));
}
function selectLatestResult(workflowState) {
    if (workflowState.finalResult !== null &&
        (0, tree_1.selectWorkflowPlanProgress)(workflowState.plan).isCompleted) {
        return (0, results_1.coerceCanonicalWorkflowFinalResult)(workflowState.finalResult);
    }
    const plan = workflowState.plan;
    if (plan === null) {
        return null;
    }
    for (let index = plan.steps.length - 1; index >= 0; index -= 1) {
        const result = (0, results_1.coerceCanonicalWorkflowResult)(plan.steps[index]?.result);
        if (result !== null) {
            return result;
        }
    }
    return null;
}
function selectActionRequiredLines(workflowState) {
    const stepResult = selectCurrentStepResult(workflowState);
    if (stepResult !== null &&
        stepResult.outcome === "wait_human" &&
        stepResult.humanComment !== null) {
        const lines = selectActionRequiredLinesFromResult(stepResult);
        return lines.length > 0 ? lines : null;
    }
    const finalResult = (0, results_1.coerceCanonicalWorkflowFinalResult)(workflowState.finalResult);
    if (finalResult !== null &&
        (0, tree_1.selectWorkflowPlanProgress)(workflowState.plan).isCompleted &&
        finalResult.outcome === "wait_human" &&
        finalResult.humanComment !== null) {
        const lines = selectActionRequiredLinesFromResult(finalResult);
        return lines.length > 0 ? lines : null;
    }
    return null;
}
function selectActionRequiredLinesFromResult(result) {
    const line = (0, helpers_1.flattenMarkdownSummary)(result.humanComment);
    return line === null ? [] : [line];
}
function selectCurrentStepResult(workflowState) {
    const plan = workflowState.plan;
    if (plan === null || plan.steps.length === 0) {
        return null;
    }
    const currentStepIndex = (0, tree_1.selectWorkflowPlanProgress)(plan).currentStepIndex;
    if (currentStepIndex === null) {
        return null;
    }
    return (0, results_1.coerceCanonicalWorkflowResult)(plan.steps[currentStepIndex]?.result);
}
function renderCurrentStepSummary(workflowState, locale) {
    const phase = (0, tree_1.resolveWorkflowDisplayPhase)(workflowState);
    const schedulingLabelKey = (0, scheduling_1.resolveSchedulingCurrentLabelKey)(workflowState);
    if (schedulingLabelKey !== null) {
        return (0, catalog_1.translate)(locale, defs_1.CANONICAL_WORKFLOW_COMMENT_LABEL_KEYS[schedulingLabelKey]);
    }
    const plan = workflowState.plan;
    if (plan === null || plan.steps.length === 0) {
        if (phase === "foreign_approval") {
            return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusAssigneeApprovalLabel");
        }
        if (phase === "start_approval") {
            return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusPlanExecutionPendingLabel");
        }
        if ((0, tree_1.isWorkflowPlanningInProgress)(workflowState)) {
            return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusPlanningLabel");
        }
        return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusCurrentStepUnavailableLabel");
    }
    const displayTree = (0, tree_1.buildDisplayTree)(workflowState);
    const currentStepNode = displayTree.currentStepNode;
    if (currentStepNode === null) {
        return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusCurrentStepUnavailableLabel");
    }
    const currentStep = currentStepNode.step;
    const currentStepResult = (0, results_1.coerceCanonicalWorkflowResult)(currentStep.result);
    const status = currentStepResult?.outcome === "fail"
        ? (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusFailedLabel")
        : phase === "done"
            ? (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusDoneLabel")
            : phase === "pending"
                ? (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusPendingLabel")
                : phase === "foreign_approval"
                    ? (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusAssigneeApprovalLabel")
                    : phase === "start_approval"
                        ? (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusPlanExecutionPendingLabel")
                        : (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusInProgressLabel");
    return `${status} (${resolveTopLevelStepPosition(displayTree, currentStepNode)}/${displayTree.topLevelTotalCount}) ${(0, helpers_1.renderWorkflowStepTitleWithIssueRef)(currentStep)}`;
}
function renderNextSummary(workflowState, locale, displayTimeZone, issueId) {
    if ((0, tree_1.resolveWorkflowDisplayPhase)(workflowState) === "foreign_approval") {
        return (0, approval_instructions_1.buildForeignApprovalNext)(locale, requireIssueIdForForeignApproval(issueId));
    }
    if ((0, tree_1.resolveWorkflowDisplayPhase)(workflowState) === "start_approval") {
        return (0, start_approval_1.renderStartApprovalNextAction)(locale, workflowState, issueId);
    }
    const actionRequired = selectActionRequiredLines(workflowState);
    if (actionRequired !== null) {
        return `${(0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusNeedFromYouLabel")}: ${actionRequired[0] ?? ""}`.trim();
    }
    if ((0, scheduling_1.isScheduledRunWorkflowState)(workflowState)) {
        return workflowState.scheduledRun?.runAt
            ? `${(0, catalog_1.translate)(locale, (0, scheduled_run_1.isCooldownScheduledRun)(workflowState)
                ? "canonicalWorkflowComment.cooldownRetryAtLabel"
                : "canonicalWorkflowComment.scheduledRunAtLabel")}: ${(0, display_time_1.formatHumanTimestamp)(workflowState.scheduledRun.runAt, locale, displayTimeZone)}.`
            : (0, catalog_1.translate)(locale, (0, scheduled_run_1.isCooldownScheduledRun)(workflowState)
                ? "canonicalWorkflowComment.cooldownWaitingLabel"
                : "canonicalWorkflowComment.scheduledRunWaitingLabel");
    }
    const plan = workflowState.plan;
    if (plan === null || plan.steps.length === 0) {
        if ((0, scheduling_1.isRecurringScheduleOnlyWorkflowState)(workflowState)) {
            return workflowState.nextRunAt
                ? `${(0, catalog_1.translate)(locale, "canonicalWorkflowComment.recurringNextRunLabel")}: ${(0, display_time_1.formatHumanTimestamp)(workflowState.nextRunAt, locale, displayTimeZone)}.`
                : (0, catalog_1.translate)(locale, "canonicalWorkflowComment.recurringScheduleWaitingLabel");
        }
        if ((0, tree_1.isWorkflowPlanningInProgress)(workflowState)) {
            return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusPlanningNextLabel");
        }
        return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusWorkflowPlanUnavailableLabel");
    }
    const progress = (0, tree_1.selectWorkflowPlanProgress)(plan);
    if (progress.isCompleted) {
        return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusWorkflowCompleteLabel");
    }
    const currentStepIndex = progress.currentStepIndex;
    if (currentStepIndex === null) {
        return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusWorkflowPlanUnavailableLabel");
    }
    const displayTree = (0, tree_1.buildDisplayTree)(workflowState);
    const currentStepNode = displayTree.currentStepNode;
    const currentStep = currentStepNode?.step;
    const currentStepResult = (0, results_1.coerceCanonicalWorkflowResult)(currentStep?.result);
    if (currentStepResult?.outcome === "fail") {
        return (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusFailedLabel");
    }
    return currentStep === undefined
        ? (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusWorkflowPlanUnavailableLabel")
        : (0, catalog_1.translate)(locale, "canonicalWorkflowComment.currentStatusAiWillRunSentence", {
            currentStep: currentStepNode
                ? resolveTopLevelStepPosition(displayTree, currentStepNode)
                : currentStepIndex + 1,
            totalSteps: displayTree.topLevelTotalCount > 0
                ? displayTree.topLevelTotalCount
                : plan.steps.length,
            stepTitle: (0, helpers_1.renderWorkflowStepTitleWithIssueRef)(currentStep),
        });
}
function resolveTopLevelStepPosition(displayTree, stepNode) {
    return Math.min(Math.max(stepNode.pathSegments[0] ?? stepNode.flatIndex + 1, 1), Math.max(displayTree.topLevelTotalCount, 1));
}
function requireIssueIdForForeignApproval(issueId) {
    if (issueId === undefined || issueId === null) {
        throw new Error("issueId is required for foreign approval instructions.");
    }
    return issueId;
}
