"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SERVICE_RUNTIME_DECISION_RULES = void 0;
exports.resolveServiceRuntimePlanSpec = resolveServiceRuntimePlanSpec;
const control_plane_config_1 = require("../../config/control-plane-config");
const catalog_1 = require("../../i18n/catalog");
const types_1 = require("../../platform/workflow-state/types");
const publisher_1 = require("../../workflows/publisher");
const config_override_validation_1 = require("../../workflows/config-override-validation");
const publisher_events_1 = require("../../workflows/publisher-events");
const run_context_summaries_1 = require("../../workflows/run-context-summaries");
const visible_update_builders_1 = require("../../workflows/visible-update-builders");
const workflow_projection_support_1 = require("../../workflows/workflow-projection-support");
const workflow_timeline_scan_1 = require("../../workflows/workflow-timeline-scan");
const workflow_surface_1 = require("../../run/run-once-cycle/workflow-surface");
const config_commandless_support_1 = require("./config-commandless-support");
const config_decision_approval_support_1 = require("./config-decision-approval-support");
const config_decision_support_1 = require("./config-decision-support");
const config_explicit_command_support_1 = require("./config-explicit-command-support");
const config_human_stop_support_1 = require("./config-human-stop-support");
const config_followup_label_support_1 = require("./config-followup-label-support");
const config_publish_spec_support_1 = require("./config-publish-spec-support");
exports.SERVICE_RUNTIME_DECISION_RULES = [
    tryResolveInvalidCanonicalWorkflowState,
    tryResolveUnavailableWorkerConfigOverride,
    tryResolveForeignApprovalPreemption,
    tryResolveApprove,
    tryResolveStart,
    tryResolveFollowupLabelRequest,
    tryResolveCommandless,
    tryResolveInvalidWorkflowCommand,
    tryResolveAcceptedWorkflowCommand,
];
async function resolveServiceRuntimePlanSpec(context) {
    for (const rule of exports.SERVICE_RUNTIME_DECISION_RULES) {
        const resolved = await rule(context);
        if (resolved !== null) {
            return resolved;
        }
    }
    return {
        kind: "noop",
        decisionKind: "commandless",
        targetIssueId: context.issue.id,
    };
}
async function tryResolveInvalidCanonicalWorkflowState(context) {
    if (context.canonicalWorkflowStateError === null) {
        return null;
    }
    const nextSnapshot = (0, workflow_projection_support_1.withWorkflowStatus)(context.issue.workflowState, types_1.WORKFLOW_STATUSES.aiNeedsHuman);
    return (0, config_publish_spec_support_1.buildServiceRuntimeProjectedPublishSpec)({
        decisionKind: "commandless",
        issue: context.issue,
        responseLanguage: context.responseLanguage,
        workflowState: null,
        scannedInputCursor: context.scannedInputCursor,
        commentCursorPolicyMode: publisher_1.WORKFLOW_COMMENT_CURSOR_POLICY_MODES.advanceToPublishedCommentIfSafe,
        invalidWorkflowStatePolicy: "treat_as_missing",
        visibleUpdateDedupeCursor: (0, workflow_timeline_scan_1.toWorkflowCommentCursor)(context.canonicalWorkflowStateError.comment),
        workflowLabels: context.workflowLabels,
        nextWorkflowSnapshot: nextSnapshot,
        previousWorkflowState: null,
        nextWorkflowState: null,
        previousNeedsHumanReason: context.currentNeedsHumanReason ?? publisher_events_1.WORKFLOW_NEEDS_HUMAN_REASONS.question,
        nextNeedsHumanReason: null,
        visibleUpdate: (0, visible_update_builders_1.buildWorkflowVisibleUpdate)({
            event: publisher_events_1.WORKFLOW_VISIBLE_EVENTS.humanAttentionRequested,
            summary: context.canonicalWorkflowStateError.summary,
            next: (0, catalog_1.translate)(context.responseLanguage, "run.presentation.failNext"),
        }),
    });
}
async function tryResolveUnavailableWorkerConfigOverride(context) {
    if (context.commandDecision.kind === "workflow_command") {
        return null;
    }
    const unavailableWorker = (0, config_override_validation_1.findUnavailableWorkerConfigOverride)({
        configWorkers: (0, control_plane_config_1.getConfiguredWorkerProviders)(context.config),
        patch: context.stickyState?.configOverrides,
    });
    if (unavailableWorker === null) {
        return null;
    }
    const nextSnapshot = (0, workflow_projection_support_1.withWorkflowStatus)(context.issue.workflowState, types_1.WORKFLOW_STATUSES.aiNeedsHuman);
    return (0, config_publish_spec_support_1.buildServiceRuntimeProjectedPublishSpec)({
        decisionKind: context.commandDecision.kind === "none"
            ? "commandless"
            : context.commandDecision.kind,
        issue: context.issue,
        responseLanguage: context.responseLanguage,
        workflowState: context.stickyState,
        scannedInputCursor: context.scannedInputCursor,
        commentCursorPolicyMode: publisher_1.WORKFLOW_COMMENT_CURSOR_POLICY_MODES.advanceToPublishedCommentIfSafe,
        workflowLabels: context.workflowLabels,
        nextWorkflowSnapshot: nextSnapshot,
        previousWorkflowState: context.stickyState,
        nextWorkflowState: context.stickyState,
        previousNeedsHumanReason: context.currentNeedsHumanReason,
        nextNeedsHumanReason: publisher_events_1.WORKFLOW_NEEDS_HUMAN_REASONS.question,
        visibleUpdate: (0, visible_update_builders_1.buildWorkflowVisibleUpdate)({
            event: publisher_events_1.WORKFLOW_VISIBLE_EVENTS.humanAttentionRequested,
            summary: (0, run_context_summaries_1.buildUnavailableWorkerConfigOverrideSummary)(context.responseLanguage, unavailableWorker),
            next: (0, catalog_1.translate)(context.responseLanguage, "run.presentation.failNext"),
        }),
    });
}
async function tryResolveForeignApprovalPreemption(context) {
    if (context.commandDecision.kind !== "start" &&
        context.commandDecision.kind !== "workflow_command") {
        return null;
    }
    const throughCursor = context.commandDecision.kind === "start"
        ? (0, workflow_timeline_scan_1.toWorkflowCommentCursor)(context.commandDecision.comment)
        : context.commandDecision.command.source === "comment"
            ? (0, workflow_timeline_scan_1.toWorkflowCommentCursor)(context.commandDecision.command.comment)
            : undefined;
    if (context.commandDecision.kind === "workflow_command" &&
        (0, config_override_validation_1.findUnavailableWorkerConfigOverride)({
            configWorkers: (0, control_plane_config_1.getConfiguredWorkerProviders)(context.config),
            patch: context.stickyState?.configOverrides,
        }) !== null) {
        return null;
    }
    const foreignApprovalInput = {
        config: context.config,
        ticketTracker: context.ticketTracker,
        issue: context.issue,
        comments: context.comments,
        stickyState: context.stickyState,
    };
    if (throughCursor !== undefined) {
        foreignApprovalInput.throughCursor = throughCursor;
    }
    const foreignApproval = await (0, config_decision_support_1.resolveBlockingForeignApprovalComment)(foreignApprovalInput);
    if (!foreignApproval.required) {
        return null;
    }
    return (0, config_human_stop_support_1.buildForeignApprovalPlanSpec)({
        config: context.config,
        issue: context.issue,
        stickyState: context.stickyState,
        currentNeedsHumanReason: context.currentNeedsHumanReason,
        workflowLabels: context.workflowLabels,
        responseLanguage: context.responseLanguage,
        currentWorkflowStateCommentId: context.currentWorkflowStateCommentId,
        scannedInputCursor: context.scannedInputCursor,
        triggerComment: foreignApproval.triggerComment,
    });
}
async function tryResolveApprove(context) {
    if (context.commandDecision.kind !== "approve") {
        return null;
    }
    return (0, config_explicit_command_support_1.buildApprovePlanSpec)({
        context,
        comment: context.commandDecision.comment,
    });
}
async function tryResolveStart(context) {
    if (context.commandDecision.kind !== "start") {
        return null;
    }
    return (0, config_explicit_command_support_1.buildStartPlanSpec)({
        context,
        comment: context.commandDecision.comment,
    });
}
async function tryResolveFollowupLabelRequest(context) {
    if (context.commandDecision.kind !== "none") {
        return null;
    }
    const followupLabel = (0, config_followup_label_support_1.resolveIssueFollowupRequestLabel)({
        issue: context.issue,
        workflowLabels: context.workflowLabels,
    });
    if (followupLabel === null) {
        return null;
    }
    const baseWorkflowState = context.stickyState ??
        (0, config_decision_approval_support_1.materializeServiceRuntimeWorkflowState)({
            config: context.config,
            previousState: null,
            workflowSurface: (0, workflow_surface_1.resolveWorkflowSurface)(context.issue),
        });
    const nextWorkflowState = baseWorkflowState.followup?.proposalPolicy === "always"
        ? baseWorkflowState
        : {
            ...baseWorkflowState,
            followup: {
                ...(baseWorkflowState.followup ?? {
                    proposalPolicy: "always",
                    proposalApproval: "auto",
                }),
                proposalPolicy: "always",
                proposalApproval: "auto",
            },
        };
    const planSpec = (0, config_publish_spec_support_1.buildServiceRuntimeProjectedPublishSpec)({
        decisionKind: "commandless",
        issue: context.issue,
        responseLanguage: context.responseLanguage,
        workflowState: nextWorkflowState,
        scannedInputCursor: context.scannedInputCursor,
        commentCursorPolicyMode: publisher_1.WORKFLOW_COMMENT_CURSOR_POLICY_MODES.preserve,
        workflowLabels: context.workflowLabels,
        nextWorkflowSnapshot: context.issue.workflowState,
        previousWorkflowState: context.stickyState,
        nextWorkflowState,
        previousNeedsHumanReason: context.currentNeedsHumanReason,
        nextNeedsHumanReason: context.currentNeedsHumanReason,
    });
    consumeFollowupRequestLabelPlanProjection(planSpec, followupLabel);
    return planSpec;
}
function consumeFollowupRequestLabelPlanProjection(planSpec, followupLabel) {
    planSpec.workflowProjection = planSpec.workflowProjection ?? {
        previous: planSpec.issue.workflowState,
        next: planSpec.issue.workflowState,
    };
    (0, config_followup_label_support_1.consumeFollowupRequestLabelProjection)(planSpec.workflowProjection, followupLabel);
}
async function tryResolveCommandless(context) {
    if (context.commandDecision.kind !== "none") {
        return null;
    }
    return (0, config_commandless_support_1.buildCommandlessPlanSpec)(context);
}
async function tryResolveInvalidWorkflowCommand(context) {
    if (context.commandDecision.kind !== "workflow_command" ||
        context.commandDecision.command.command.kind !== "invalid") {
        return null;
    }
    return (0, config_explicit_command_support_1.buildInvalidWorkflowCommandPlanSpec)(context);
}
async function tryResolveAcceptedWorkflowCommand(context) {
    if (context.commandDecision.kind !== "workflow_command") {
        return null;
    }
    if (context.commandDecision.command.command.kind === "invalid") {
        return null;
    }
    return (0, config_explicit_command_support_1.buildAcceptedWorkflowCommandPlanSpec)(context);
}
