export function resolveWorkflowPhaseLayers(workflowName) {
    switch (workflowName) {
        case "coordinate":
            return [];
        case "explore-build":
            return [["explore"], ["build"]];
        case "build-verify":
            return [["build"], ["verify"]];
        case "plan-build-verify":
            return [["plan"], ["build"], ["verify"]];
        case "plan-explore-build-verify":
            return [["plan", "explore"], ["build"], ["verify"]];
        default:
            return [["plan"], ["build"], ["verify"]];
    }
}
export function inferWorkflowNameFromPhaseResults(phaseResults) {
    if (phaseResults.explore && phaseResults.plan && phaseResults.build && phaseResults.verify) {
        return "plan-explore-build-verify";
    }
    if (phaseResults.explore && phaseResults.build && !phaseResults.plan && !phaseResults.verify) {
        return "explore-build";
    }
    if (phaseResults.build && phaseResults.verify && !phaseResults.explore && !phaseResults.plan) {
        return "build-verify";
    }
    return "plan-build-verify";
}
export function buildWorkflowPhaseDependencies(workflowLayers) {
    const dependencies = new Map();
    let priorLayer = [];
    for (const layer of workflowLayers) {
        for (const phaseName of layer) {
            dependencies.set(phaseName, [...priorLayer]);
        }
        priorLayer = layer;
    }
    return dependencies;
}
export function buildWorkflowPhaseEdges(workflowLayers) {
    return workflowLayers.flatMap((layer, index) => {
        const next = workflowLayers[index + 1];
        if (!next) {
            return [];
        }
        return layer.flatMap((from) => next.map((to) => ({ from, to })));
    });
}
export function resolveReadyWorkflowPhases(input) {
    const workflowDependencies = buildWorkflowPhaseDependencies(input.workflowLayers);
    return input.workflowLayers.flatMap((layer) => layer.filter((phaseName) => {
        if (!input.pendingPhases.has(phaseName)) {
            return false;
        }
        const dependencies = workflowDependencies.get(phaseName) ?? [];
        return dependencies.every((dependency) => input.completedPhases.has(dependency));
    }));
}
export function resolveWorkflowNodeAllowedTools(input) {
    const profileTools = input.profileName
        ? input.readProfileAllowedTools(input.profileName)
        : undefined;
    if (profileTools) {
        return [...profileTools];
    }
    return [...(input.readProfileAllowedTools(input.fallbackPhaseName) ?? [])];
}
export function buildWorkflowChildTaskGraphNodes(input) {
    const steps = resolveWorkflowPhaseLayers(input.workflowName);
    return steps.flatMap((step) => step.map((phaseName) => {
        const record = input.phases.get(phaseName);
        const profileName = record?.profileName ?? phaseName;
        return {
            allowedTools: resolveWorkflowNodeAllowedTools({
                fallbackPhaseName: phaseName,
                profileName,
                readProfileAllowedTools: input.readProfileAllowedTools,
            }),
            ...(record?.childThreadId ? { childThreadId: record.childThreadId } : {}),
            ...(record?.correlationId ? { correlationId: record.correlationId } : {}),
            ...(record?.childTaskId && input.effectiveVerdicts?.get(record.childTaskId)
                ? { effectiveVerdict: input.effectiveVerdicts.get(record.childTaskId) }
                : {}),
            ...(record?.childTaskId ? { nodeId: record.childTaskId } : {}),
            phaseName,
            profileName,
            status: input.statusForRecord
                ? input.statusForRecord(record)
                : (record?.status ?? "pending"),
        };
    }));
}
export function buildWorkflowChildTaskGraph(input) {
    return {
        edges: buildWorkflowPhaseEdges(resolveWorkflowPhaseLayers(input.workflowName)),
        nodes: buildWorkflowChildTaskGraphNodes(input),
    };
}
export function buildWorkflowPhaseResultGraph(input) {
    const workflowLayers = resolveWorkflowPhaseLayers(input.workflowName);
    return {
        edges: buildWorkflowPhaseEdges(workflowLayers),
        nodes: workflowLayers.flatMap((layer) => layer.map((phaseName) => ({
            allowedTools: resolveWorkflowNodeAllowedTools({
                fallbackPhaseName: phaseName,
                readProfileAllowedTools: input.readProfileAllowedTools,
            }),
            phaseName,
            profileName: phaseName,
            status: input.phaseResults[phaseName] ? "completed" : "pending",
        }))),
    };
}
export function groupWorkflowPhaseRecordsByTurn(records) {
    const latestByTurn = new Map();
    for (const record of records) {
        if (!record.phaseName || !record.workflowName) {
            continue;
        }
        let phases = latestByTurn.get(record.turnId);
        if (!phases) {
            phases = new Map();
            latestByTurn.set(record.turnId, phases);
        }
        const existing = phases.get(record.phaseName);
        if (!existing || shouldReplaceWorkflowPhaseRecord(existing, record)) {
            phases.set(record.phaseName, record);
        }
    }
    return latestByTurn;
}
function shouldReplaceWorkflowPhaseRecord(existing, candidate) {
    if (existing.childTaskId === candidate.childTaskId) {
        return childTaskStatusRank(existing.status) <= childTaskStatusRank(candidate.status);
    }
    return existing.createdAt <= candidate.createdAt;
}
function childTaskStatusRank(status) {
    switch (status) {
        case "running":
            return 0;
        case "completed":
        case "failed":
            return 1;
        case "joined":
        case "rejected":
            return 2;
    }
}
export function listWorkflowVerifyChildTaskIds(phases) {
    return Array.from(phases.values())
        .filter((record) => record.phaseName === "verify")
        .map((record) => record.childTaskId);
}
export async function collectChildTaskEffectiveVerdicts(input) {
    const selectedVerdicts = new Map();
    for (const nodeId of input.childTaskIds) {
        const verdict = input.effectiveVerdicts.get(nodeId);
        if (verdict) {
            selectedVerdicts.set(nodeId, verdict);
        }
    }
    return selectedVerdicts;
}
export async function collectWorkflowVerifyVerdicts(input) {
    return collectChildTaskEffectiveVerdicts({
        childTaskIds: listWorkflowVerifyChildTaskIds(input.phases),
        effectiveVerdicts: input.effectiveVerdicts,
    });
}
export async function collectWorkflowTurnStates(input) {
    const latestByTurn = groupWorkflowPhaseRecordsByTurn(input.records);
    const workflowTurns = [];
    for (const [turnId, phases] of latestByTurn.entries()) {
        const workflowName = phases.values().next().value?.workflowName;
        if (!workflowName) {
            continue;
        }
        workflowTurns.push({
            effectiveVerdicts: await collectWorkflowVerifyVerdicts({
                effectiveVerdicts: input.effectiveVerdicts,
                phases,
            }),
            phases,
            turnId,
            workflowName,
        });
    }
    return workflowTurns;
}
//# sourceMappingURL=workflow-graph.js.map