"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isWorkflowStepDone = isWorkflowStepDone;
exports.isWorkflowStepFailed = isWorkflowStepFailed;
exports.isWorkflowStepBlocked = isWorkflowStepBlocked;
exports.isCompletedWorkflowPlan = isCompletedWorkflowPlan;
exports.isClosedCompletedControllerChildIssue = isClosedCompletedControllerChildIssue;
exports.isMaterializedIncompleteControllerChildIssueStep = isMaterializedIncompleteControllerChildIssueStep;
exports.isUnmaterializedIncompleteControllerChildIssueStep = isUnmaterializedIncompleteControllerChildIssueStep;
exports.buildCompletedControllerChildIssueResult = buildCompletedControllerChildIssueResult;
exports.getCompletedWorkflowStepIds = getCompletedWorkflowStepIds;
exports.areWorkflowStepDependenciesSatisfied = areWorkflowStepDependenciesSatisfied;
exports.selectReadyWorkflowSteps = selectReadyWorkflowSteps;
exports.selectReadyWorkflowStepsByKind = selectReadyWorkflowStepsByKind;
exports.selectReadyTaskWorkflowSteps = selectReadyTaskWorkflowSteps;
exports.selectReadyTaskStepBatch = selectReadyTaskStepBatch;
exports.resolveWorkflowWorkerSlotDemand = resolveWorkflowWorkerSlotDemand;
exports.selectReadyWorkflowRefStep = selectReadyWorkflowRefStep;
exports.selectReadyNestedWorkflowPlanningStep = selectReadyNestedWorkflowPlanningStep;
exports.selectReadyControllerChildIssueSteps = selectReadyControllerChildIssueSteps;
exports.selectUnmaterializedReadyControllerChildIssueSteps = selectUnmaterializedReadyControllerChildIssueSteps;
exports.hasWorkflowWorkerExecutableAction = hasWorkflowWorkerExecutableAction;
exports.hasWorkflowHumanResumeExecutableAction = hasWorkflowHumanResumeExecutableAction;
exports.hasUnmaterializedReadyControllerChildIssueAction = hasUnmaterializedReadyControllerChildIssueAction;
exports.selectNextReadyWorkflowStep = selectNextReadyWorkflowStep;
exports.selectNextExecutableWorkflowStep = selectNextExecutableWorkflowStep;
exports.selectNextControllerChildIssueStep = selectNextControllerChildIssueStep;
exports.hasMaterializedSelectedControllerChildIssue = hasMaterializedSelectedControllerChildIssue;
exports.hasControllerChildIssueControlPlaneAction = hasControllerChildIssueControlPlaneAction;
exports.hasStartableWorkflowPlan = hasStartableWorkflowPlan;
exports.findWorkflowStepIndexById = findWorkflowStepIndexById;
exports.findWorkflowStepById = findWorkflowStepById;
exports.withWorkflowPlanStepResultById = withWorkflowPlanStepResultById;
const issue_ref_1 = require("./issue-ref");
const types_1 = require("./types");
function isWorkflowStepDone(step) {
    return step.result?.outcome === "proceed";
}
function isWorkflowStepFailed(step) {
    return step.result?.outcome === "fail";
}
function isWorkflowStepBlocked(step) {
    return step.result?.outcome === "wait_human";
}
function isCompletedWorkflowPlan(plan) {
    if (plan === null || plan.steps.length === 0) {
        return false;
    }
    return plan.steps.every(isWorkflowStepDone);
}
function isClosedCompletedControllerChildIssue(input) {
    return (!input.issue.isOpen &&
        isCompletedWorkflowPlan(input.workflowState?.plan ?? null));
}
function isMaterializedIncompleteControllerChildIssueStep(step) {
    return ((0, types_1.isWorkflowChildIssueStep)(step) &&
        step.result === null &&
        (0, issue_ref_1.normalizeWorkflowIssueDisplayRef)(step.childIssueRef) !== null);
}
function isUnmaterializedIncompleteControllerChildIssueStep(step) {
    return ((0, types_1.isWorkflowChildIssueStep)(step) &&
        step.result === null &&
        (0, issue_ref_1.normalizeWorkflowIssueDisplayRef)(step.childIssueRef) === null);
}
function buildCompletedControllerChildIssueResult(input) {
    const resultSummary = resolveCompletedControllerChildIssueSummary(input);
    const evidence = [
        `Closed child issue completed its workflow plan: ${input.issue.baseTitle}`,
    ];
    if (resultSummary !== input.issue.baseTitle) {
        evidence.push(`Child issue result summary: ${resultSummary}`);
    }
    return (0, types_1.buildWorkflowResultWithDefaults)({
        outcome: "proceed",
        resultSummary,
        evidence,
    });
}
function resolveCompletedControllerChildIssueSummary(input) {
    const finalSummary = normalizeWorkflowResultSummary(input.workflowState.finalResult?.resultSummary);
    if (finalSummary !== null) {
        return finalSummary;
    }
    for (let index = (input.workflowState.plan?.steps.length ?? 0) - 1; index >= 0; index -= 1) {
        const result = input.workflowState.plan?.steps[index]?.result;
        if (result?.outcome !== "proceed") {
            continue;
        }
        const stepSummary = normalizeWorkflowResultSummary(result.resultSummary);
        if (stepSummary !== null) {
            return stepSummary;
        }
    }
    return input.issue.baseTitle;
}
function normalizeWorkflowResultSummary(value) {
    const trimmed = value?.trim();
    return trimmed === undefined || trimmed.length === 0 ? null : trimmed;
}
function getCompletedWorkflowStepIds(steps) {
    return new Set(steps.filter((step) => isWorkflowStepDone(step)).map((step) => step.id));
}
function areWorkflowStepDependenciesSatisfied(step, completedStepIds) {
    return step.dependsOnStepIds.every((dependencyId) => completedStepIds.has(dependencyId));
}
function selectReadyWorkflowSteps(plan) {
    const completedStepIds = getCompletedWorkflowStepIds(plan.steps);
    return plan.steps.filter((step) => step.result === null &&
        areWorkflowStepDependenciesSatisfied(step, completedStepIds));
}
function selectReadyWorkflowStepsByKind(plan, kind) {
    return selectReadyWorkflowSteps(plan).filter((step) => step.kind === kind);
}
function selectReadyTaskWorkflowSteps(plan) {
    return selectReadyWorkflowStepsByKind(plan, "task");
}
function selectReadyTaskStepBatch(plan, workerSlotBudget) {
    if (workerSlotBudget <= 0) {
        return [];
    }
    return selectReadyTaskWorkflowSteps(plan).slice(0, workerSlotBudget);
}
function resolveWorkflowWorkerSlotDemand(workflowState) {
    if (workflowState === null || workflowState.plan === null) {
        return 1;
    }
    if (selectReadyWorkflowRefStep(workflowState.plan) !== null) {
        return 1;
    }
    return Math.max(1, selectReadyTaskWorkflowSteps(workflowState.plan).length);
}
function selectReadyWorkflowRefStep(plan) {
    return selectReadyWorkflowStepsByKind(plan, "workflow_ref")[0] ?? null;
}
function selectReadyNestedWorkflowPlanningStep(plan) {
    return (selectReadyWorkflowSteps(plan).find((step) => step.kind === "workflow_ref" ||
        (step.originWorkflowRef !== undefined &&
            step.originSubtreeKey !== undefined &&
            step.sourceTemplateName !== undefined &&
            step.sourceTemplateDigest !== undefined)) ?? null);
}
function selectReadyControllerChildIssueSteps(plan) {
    return selectReadyWorkflowStepsByKind(plan, "child_issue").filter(types_1.isWorkflowChildIssueStep);
}
function selectUnmaterializedReadyControllerChildIssueSteps(plan) {
    return selectReadyControllerChildIssueSteps(plan).filter(isUnmaterializedIncompleteControllerChildIssueStep);
}
function hasWorkflowWorkerExecutableAction(workflowState) {
    if (workflowState?.pendingPlanningIntent !== undefined) {
        return true;
    }
    if (workflowState?.plan === null || workflowState === null) {
        return true;
    }
    return selectReadyWorkflowSteps(workflowState.plan).some((step) => step.kind !== "child_issue");
}
function hasWorkflowHumanResumeExecutableAction(workflowState) {
    if (workflowState?.pendingPlanningIntent !== undefined) {
        return true;
    }
    if (workflowState?.plan === null || workflowState === null) {
        return true;
    }
    return (hasWorkflowWorkerExecutableAction(workflowState) ||
        workflowState.plan.steps.some(isWorkflowStepBlocked));
}
function hasUnmaterializedReadyControllerChildIssueAction(workflowState) {
    if (workflowState?.plan === null || workflowState === null) {
        return false;
    }
    return (selectUnmaterializedReadyControllerChildIssueSteps(workflowState.plan)
        .length > 0);
}
function selectNextReadyWorkflowStep(plan) {
    return selectReadyWorkflowSteps(plan)[0] ?? null;
}
function selectNextExecutableWorkflowStep(plan) {
    const nextReadyStep = selectNextReadyWorkflowStep(plan);
    return nextReadyStep?.kind === "child_issue" ? null : (nextReadyStep ?? null);
}
function selectNextControllerChildIssueStep(plan) {
    const nextReadyStep = selectNextReadyWorkflowStep(plan);
    return (0, types_1.isWorkflowChildIssueStep)(nextReadyStep) ? nextReadyStep : null;
}
function hasMaterializedSelectedControllerChildIssue(workflowState) {
    if (workflowState?.plan === null || workflowState === null) {
        return false;
    }
    const selectedChildStep = selectNextControllerChildIssueStep(workflowState.plan);
    return isMaterializedIncompleteControllerChildIssueStep(selectedChildStep);
}
function hasControllerChildIssueControlPlaneAction(workflowState) {
    if (workflowState === null) {
        return false;
    }
    if ((workflowState.pendingChildIssueDecisions ?? []).length > 0) {
        return true;
    }
    if (workflowState.plan === null) {
        return false;
    }
    if (!workflowState.plan.steps.some((step) => step.kind === "child_issue")) {
        return false;
    }
    return (selectReadyControllerChildIssueSteps(workflowState.plan).length > 0 ||
        (selectNextReadyWorkflowStep(workflowState.plan) === null &&
            isCompletedWorkflowPlan(workflowState.plan)));
}
function hasStartableWorkflowPlan(workflowState) {
    if (workflowState?.plan === null || workflowState === null) {
        return false;
    }
    return selectNextReadyWorkflowStep(workflowState.plan) !== null;
}
function findWorkflowStepIndexById(plan, stepId) {
    return plan.steps.findIndex((step) => step.id === stepId);
}
function findWorkflowStepById(plan, stepId) {
    return plan.steps.find((step) => step.id === stepId) ?? null;
}
function withWorkflowPlanStepResultById(plan, stepId, result) {
    return {
        steps: plan.steps.map((step) => step.id === stepId ? { ...step, result } : step),
    };
}
