"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveWorkflowPlanningArtifacts = void 0;
exports.resolveWorkflowRunRouteResult = resolveWorkflowRunRouteResult;
exports.resolveWorkflowPlanningContextForSelection = resolveWorkflowPlanningContextForSelection;
exports.resolveNestedWorkflowPlanningContext = resolveNestedWorkflowPlanningContext;
const control_plane_config_1 = require("../config/control-plane-config");
const catalog_1 = require("../i18n/catalog");
const types_1 = require("../worker/types");
const default_system_workflows_1 = require("./default-system-workflows");
const required_mcp_1 = require("./required-mcp");
const required_skills_1 = require("./required-skills");
const run_context_result_builders_1 = require("./run-context-result-builders");
const run_context_state_builders_1 = require("./run-context-state-builders");
const run_context_template_artifacts_1 = require("./run-context-template-artifacts");
const state_1 = require("./state");
const template_bindings_1 = require("./template-bindings");
const workflow_contract_1 = require("./workflow-contract");
const workflow_template_targets_1 = require("./workflow-template-targets");
var run_context_template_artifacts_2 = require("./run-context-template-artifacts");
Object.defineProperty(exports, "resolveWorkflowPlanningArtifacts", { enumerable: true, get: function () { return run_context_template_artifacts_2.resolveWorkflowPlanningArtifacts; } });
async function resolveWorkflowRunRouteResult(input) {
    const workflowState = (0, run_context_state_builders_1.buildWorkflowStateForRoute)({
        prepared: input.prepared,
        route: input.route,
    });
    const followup = resolveWorkerFollowupConfig({
        workflowStartApprovalConfig: input.workflowStartApprovalConfig,
        workflowState,
        fallbackMaxIssuesPerSource: input.followupMaxIssuesPerSource,
    });
    const activeTemplateName = (0, template_bindings_1.getWorkflowTemplateName)(input.prepared.resolution.binding);
    switch (input.route.kind) {
        case "select": {
            const artifacts = input.route.branch === "select_with_template"
                ? await resolveWorkflowRouteArtifacts({
                    repoRoot: input.repoRoot,
                    locale: input.locale,
                    maxNestedWorkflowDepth: input.maxNestedWorkflowDepth,
                    catalog: input.prepared.catalog,
                    workflowState,
                    template: input.prepared.resolution.template,
                    templateName: activeTemplateName,
                    branch: input.route.branch,
                })
                : null;
            if (artifacts !== null && "kind" in artifacts) {
                return artifacts;
            }
            return (0, run_context_result_builders_1.buildWorkflowSelectResult)({
                prepared: input.prepared,
                workflowState,
                planningIntent: input.route.planningIntent,
                issueCompletion: input.issueCompletion,
                issueNotesPath: input.issueNotesPath,
                followupMaxIssuesPerSource: followup.maxIssuesPerSource,
                followupPreferredWorkflowTemplates: followup.preferredWorkflowTemplates,
                followupAutoMaintainTemplates: followup.autoMaintainTemplates,
                artifacts,
            });
        }
        case "plan": {
            const artifacts = input.route.branch === "plan_template"
                ? await resolveWorkflowRouteArtifacts({
                    repoRoot: input.repoRoot,
                    locale: input.locale,
                    maxNestedWorkflowDepth: input.maxNestedWorkflowDepth,
                    catalog: input.prepared.catalog,
                    workflowState,
                    template: input.prepared.resolution.template,
                    templateName: activeTemplateName,
                    branch: input.route.branch,
                })
                : null;
            if (artifacts !== null && "kind" in artifacts) {
                return artifacts;
            }
            return (0, run_context_result_builders_1.buildWorkflowPlanResult)({
                workflowTemplateName: activeTemplateName,
                workflowState,
                planningIntent: input.route.planningIntent,
                requiresPreflightReplan: input.route.requiresPreflightReplan,
                issueCompletion: input.issueCompletion,
                issueNotesPath: input.issueNotesPath,
                followupMaxIssuesPerSource: followup.maxIssuesPerSource,
                followupPreferredWorkflowTemplates: followup.preferredWorkflowTemplates,
                followupAutoMaintainTemplates: followup.autoMaintainTemplates,
                startApprovalMode: resolveOptionalWorkflowStartApprovalMode({
                    config: input.workflowStartApprovalConfig,
                    workflowState,
                    target: input.workflowStartApprovalTarget,
                    planningIntent: input.route.planningIntent,
                }),
                workflowSurface: input.prepared.workflowSurface,
                templateName: activeTemplateName,
                commandContext: input.prepared.appliedCommandState.commandContext,
                artifacts,
            });
        }
        case "execute":
            return (0, run_context_result_builders_1.buildWorkflowExecuteResult)({
                workflowTemplateName: activeTemplateName,
                workflowState,
                issueCompletion: input.issueCompletion,
                issueNotesPath: input.issueNotesPath,
                followupMaxIssuesPerSource: followup.maxIssuesPerSource,
                followupPreferredWorkflowTemplates: followup.preferredWorkflowTemplates,
                followupAutoMaintainTemplates: followup.autoMaintainTemplates,
                workflowSurface: input.prepared.workflowSurface,
                templateName: activeTemplateName,
                requiredSkills: input.prepared.resolution.template === null
                    ? []
                    : (0, required_skills_1.collectRequiredSkillsForWorkflowTree)({
                        catalog: input.prepared.catalog,
                        rootTemplate: input.prepared.resolution.template,
                        maxNestedWorkflowDepth: input.maxNestedWorkflowDepth,
                    }),
                requiredMcp: input.prepared.resolution.template === null
                    ? []
                    : (0, required_mcp_1.collectRequiredMcpForWorkflowTree)({
                        catalog: input.prepared.catalog,
                        rootTemplate: input.prepared.resolution.template,
                        maxNestedWorkflowDepth: input.maxNestedWorkflowDepth,
                    }),
            });
    }
}
async function resolveWorkflowPlanningContextForSelection(input) {
    const locale = input.locale ?? catalog_1.DEFAULT_APP_LOCALE;
    const workflowSurface = input.workflowSurface ?? "issue";
    const issueCompletion = input.issueCompletion ??
        (0, control_plane_config_1.resolveIssueEffectiveConfigForWorkflowState)(control_plane_config_1.DEFAULT_CONFIG, input.workflowState.configOverrides === undefined
            ? {
                baseBranch: input.workflowState.baseBranch,
            }
            : {
                baseBranch: input.workflowState.baseBranch,
                configOverrides: input.workflowState.configOverrides,
            }).issueCompletion;
    const maxNestedWorkflowDepth = input.maxNestedWorkflowDepth ?? control_plane_config_1.DEFAULT_CONFIG.maxNestedWorkflowDepth;
    const followupMaxIssuesPerSource = input.followupMaxIssuesPerSource ??
        control_plane_config_1.DEFAULT_CONFIG.followup.maxIssuesPerSource;
    const followupPreferredWorkflowTemplates = [
        ...(input.followupPreferredWorkflowTemplates ??
            control_plane_config_1.DEFAULT_CONFIG.followup.preferredWorkflowTemplates),
    ];
    const followupAutoMaintainTemplates = input.followupAutoMaintainTemplates ??
        control_plane_config_1.DEFAULT_CONFIG.followup.autoMaintainTemplates;
    const issueNotesPath = input.issueNotesPath;
    const catalog = await (0, run_context_template_artifacts_1.loadWorkflowTemplateCatalogOrHandoff)({
        repoRoot: input.repoRoot,
        locale,
        workflowState: input.workflowState,
    });
    if ("kind" in catalog) {
        return catalog;
    }
    const baseSelectors = (0, template_bindings_1.createWorkflowTemplateSelectorMap)({
        workflowTemplates: input.workflowState.workflowTemplates,
    });
    let workflowTemplates;
    try {
        workflowTemplates = (0, template_bindings_1.resolveWorkflowTemplateBindings)({
            catalog,
            selectors: baseSelectors,
        });
    }
    catch (error) {
        if ((0, template_bindings_1.isMissingDefaultSystemWorkflowTemplateError)(error)) {
            return (0, run_context_template_artifacts_1.buildMissingWorkflowTemplateHandoff)({
                catalog,
                templateName: error.templatePath,
                workflowSurface: error.surface,
                locale,
                workflowState: null,
                selection: { mode: "no_template" },
            });
        }
        throw error;
    }
    const workflowState = {
        ...input.workflowState,
        workflowSurface,
        workflowTemplates,
    };
    const activeBinding = (0, template_bindings_1.getActiveWorkflowTemplateBinding)(workflowState);
    const activeTemplateName = (0, template_bindings_1.getWorkflowTemplateName)(activeBinding);
    const selectedTemplateName = input.templateName ??
        (activeBinding?.selector.mode === "no_template"
            ? activeTemplateName
            : null);
    if (selectedTemplateName === null) {
        const defaultTemplatePath = activeBinding?.selector.mode === "no_template"
            ? (0, default_system_workflows_1.resolveDefaultSystemWorkflowTemplatePath)(workflowSurface)
            : null;
        if (defaultTemplatePath !== null) {
            return (0, run_context_template_artifacts_1.buildMissingWorkflowTemplateHandoff)({
                catalog,
                templateName: defaultTemplatePath,
                workflowSurface,
                locale,
                workflowState: null,
                selection: { mode: "no_template" },
            });
        }
        return (0, run_context_result_builders_1.buildWorkflowPlanResult)({
            workflowTemplateName: null,
            workflowState,
            planningIntent: input.planningIntent,
            requiresPreflightReplan: false,
            issueCompletion,
            issueNotesPath,
            followupMaxIssuesPerSource,
            followupPreferredWorkflowTemplates,
            followupAutoMaintainTemplates,
            startApprovalMode: input.workflowStartApprovalMode,
            workflowSurface,
            templateName: null,
            commandContext: input.commandContext ?? null,
            artifacts: null,
        });
    }
    const template = (0, run_context_template_artifacts_1.resolveWorkflowPlanningTemplateOrHandoff)({
        catalog,
        templateName: selectedTemplateName,
        workflowSurface,
        locale,
        workflowState,
    });
    if ("kind" in template) {
        return template;
    }
    const artifacts = await (0, run_context_template_artifacts_1.resolveWorkflowPlanningArtifacts)({
        repoRoot: input.repoRoot,
        template,
        templateName: template.templatePath,
        catalog,
        locale,
        maxNestedWorkflowDepth,
        workflowState,
    });
    if ("kind" in artifacts) {
        return artifacts;
    }
    return (0, run_context_result_builders_1.buildWorkflowPlanResult)({
        workflowTemplateName: template.templatePath,
        workflowState,
        planningIntent: input.planningIntent,
        requiresPreflightReplan: false,
        issueCompletion,
        issueNotesPath,
        followupMaxIssuesPerSource,
        followupPreferredWorkflowTemplates,
        followupAutoMaintainTemplates,
        startApprovalMode: input.workflowStartApprovalMode,
        workflowSurface,
        templateName: template.templatePath,
        commandContext: input.commandContext ?? null,
        artifacts,
    });
}
function resolveOptionalWorkflowStartApprovalMode(input) {
    if (input.config === undefined || input.target === undefined) {
        return undefined;
    }
    const effectiveConfig = (0, control_plane_config_1.resolveIssueEffectiveConfigForWorkflowState)(input.config, input.workflowState);
    const startApprovalIntent = input.workflowState.pendingWorkflowStartApprovalIntent;
    return (0, control_plane_config_1.resolveWorkflowStartApprovalModeForPlanningIntent)({
        target: input.target,
        planningIntent: input.planningIntent,
        ...(startApprovalIntent === undefined ? {} : { startApprovalIntent }),
        config: effectiveConfig,
    });
}
function resolveWorkerFollowupConfig(input) {
    if (input.workflowStartApprovalConfig === undefined) {
        return {
            maxIssuesPerSource: input.fallbackMaxIssuesPerSource,
            preferredWorkflowTemplates: [
                ...control_plane_config_1.DEFAULT_CONFIG.followup.preferredWorkflowTemplates,
            ],
            autoMaintainTemplates: control_plane_config_1.DEFAULT_CONFIG.followup.autoMaintainTemplates,
        };
    }
    const effectiveConfig = (0, control_plane_config_1.resolveIssueEffectiveConfigForWorkflowState)(input.workflowStartApprovalConfig, input.workflowState);
    return {
        maxIssuesPerSource: effectiveConfig.followup.maxIssuesPerSource,
        preferredWorkflowTemplates: [
            ...effectiveConfig.followup.preferredWorkflowTemplates,
        ],
        autoMaintainTemplates: effectiveConfig.followup.autoMaintainTemplates,
    };
}
async function resolveWorkflowRouteArtifacts(input) {
    if (input.template === null || input.templateName === null) {
        throw new Error(`${input.branch} requires an active template`);
    }
    return (0, run_context_template_artifacts_1.resolveWorkflowPlanningArtifacts)({
        repoRoot: input.repoRoot,
        template: input.template,
        templateName: input.templateName,
        catalog: input.catalog,
        locale: input.locale,
        maxNestedWorkflowDepth: input.maxNestedWorkflowDepth,
        workflowState: input.workflowState,
    });
}
async function resolveNestedWorkflowPlanningContext(input) {
    const locale = input.locale ?? catalog_1.DEFAULT_APP_LOCALE;
    const maxNestedWorkflowDepth = input.maxNestedWorkflowDepth ?? control_plane_config_1.DEFAULT_CONFIG.maxNestedWorkflowDepth;
    const catalog = await (0, run_context_template_artifacts_1.loadWorkflowTemplateCatalogOrHandoff)({
        repoRoot: input.repoRoot,
        locale,
        workflowState: input.workflowState,
    });
    if ("kind" in catalog) {
        return catalog;
    }
    const targetTemplate = (0, run_context_template_artifacts_1.resolveNestedWorkflowChildTemplateOrHandoff)({
        catalog,
        targetTemplateName: input.targetTemplateName,
        sourceTemplateName: input.sourceTemplateName,
        parentStepTitle: input.parentStepTitle,
        locale,
        workflowState: input.workflowState,
    });
    if ("kind" in targetTemplate) {
        return targetTemplate;
    }
    const activeTemplateName = (0, template_bindings_1.getWorkflowTemplateName)((0, template_bindings_1.getActiveWorkflowTemplateBinding)(input.workflowState));
    const sourceTemplateDigest = resolveNestedSourceTemplateDigest({
        catalog,
        workflowState: input.workflowState,
        sourceTemplateName: input.sourceTemplateName,
    });
    if (sourceTemplateDigest === null) {
        return (0, run_context_template_artifacts_1.buildMissingWorkflowTemplateHandoff)({
            catalog,
            templateName: input.sourceTemplateName,
            workflowSurface: input.workflowState.workflowSurface,
            locale,
            workflowState: input.workflowState,
            workflowTemplateName: activeTemplateName,
            selection: {
                mode: "template",
                templatePath: input.sourceTemplateName,
            },
        });
    }
    const activeStack = [activeTemplateName, input.sourceTemplateName].filter((value, index, values) => {
        return typeof value === "string" && values.indexOf(value) === index;
    });
    const artifacts = await (0, run_context_template_artifacts_1.resolveNestedWorkflowPlanningArtifacts)({
        repoRoot: input.repoRoot,
        activeStack,
        activeTemplateName,
        catalog,
        currentDepth: Math.max(activeStack.length - 1, 0),
        locale,
        maxNestedWorkflowDepth,
        parentStepTitle: input.parentStepTitle,
        targetTemplate,
        targetTemplateName: input.targetTemplateName,
        workflowState: input.workflowState,
    });
    if ("kind" in artifacts) {
        return artifacts;
    }
    const childWorkflowState = buildNestedWorkflowChildPlanningState({
        workflowState: input.workflowState,
        workflowSurface: resolveNestedWorkflowSurface({
            parentSurface: input.workflowState.workflowSurface,
            targetTemplate,
        }),
        templatePath: targetTemplate.templatePath,
        templateDigest: targetTemplate.digest,
    });
    return buildNestedWorkflowPlanningContinuation({
        input,
        sourceTemplateDigest,
        targetTemplate,
        childWorkflowState,
        artifacts,
    });
}
function buildNestedWorkflowChildPlanningState(input) {
    const childWorkflowStateInput = {
        workflowSurface: input.workflowSurface,
        workflowTemplates: (0, template_bindings_1.setWorkflowTemplateBinding)({
            workflowTemplates: input.workflowState.workflowTemplates,
            surface: input.workflowSurface,
            binding: (0, template_bindings_1.createWorkflowTemplateBinding)({
                selector: { mode: "template", templatePath: input.templatePath },
                resolution: {
                    kind: "template",
                    templatePath: input.templatePath,
                    digest: input.templateDigest,
                },
            }),
        }),
        baseBranch: input.workflowState.baseBranch,
        priorityRank: input.workflowState.priorityRank ?? null,
        executionContract: (0, workflow_contract_1.createDefaultWorkflowExecutionContract)(),
        plan: null,
        predictedTouchedPaths: [],
    };
    if (input.workflowState.schedule !== undefined) {
        childWorkflowStateInput.schedule = input.workflowState.schedule;
    }
    if (input.workflowState.configOverrides !== undefined) {
        childWorkflowStateInput.configOverrides =
            input.workflowState.configOverrides;
    }
    return (0, state_1.buildPersistedWorkflowState)(childWorkflowStateInput);
}
function buildNestedWorkflowPlanningContinuation(input) {
    const workflow = {
        mode: types_1.WORKER_RUN_MODES.workflowPlan,
        templateName: input.targetTemplate.templatePath,
        planningIntent: "new_plan",
        workflowSurface: input.childWorkflowState.workflowSurface,
        templateBody: input.artifacts.templateBody,
        requiredSkills: input.artifacts.requiredSkills,
        requiredMcp: input.artifacts.requiredMcp,
        directChildWorkflows: input.artifacts.directChildWorkflows ?? null,
        templateReferences: input.artifacts.templateReferences ?? null,
        issueNotesPath: input.input.issueNotesPath,
        state: input.childWorkflowState,
    };
    return {
        kind: "continue",
        workflow,
        workflowTemplateName: input.targetTemplate.templatePath,
        workflowState: input.childWorkflowState,
        templateDigest: input.targetTemplate.digest,
        sourceTemplateDigest: input.sourceTemplateDigest,
    };
}
function resolveNestedWorkflowSurface(input) {
    const targets = (0, workflow_template_targets_1.resolveWorkflowTemplateRecordTargets)(input.targetTemplate);
    return input.parentSurface !== "merge" &&
        targets.includes(input.parentSurface)
        ? input.parentSurface
        : (targets[0] ?? "issue");
}
function resolveNestedSourceTemplateDigest(input) {
    const activeBinding = (0, template_bindings_1.getActiveWorkflowTemplateBinding)(input.workflowState);
    if (input.sourceTemplateName === (0, template_bindings_1.getWorkflowTemplateName)(activeBinding)) {
        return (0, template_bindings_1.getWorkflowTemplateDigest)(activeBinding);
    }
    return (input.catalog.templateByPath.get(input.sourceTemplateName)?.digest ?? null);
}
