/**
 * Wave computation and dependency graph operations.
 * @task T4784
 */
import { getAccessor } from '../store/data-accessor.js';
/** Build a dependency graph for tasks. */
function buildDependencyGraph(tasks) {
    const graph = new Map();
    for (const task of tasks) {
        if (!graph.has(task.id)) {
            graph.set(task.id, new Set());
        }
        if (task.depends) {
            for (const dep of task.depends) {
                graph.get(task.id).add(dep);
            }
        }
    }
    return graph;
}
/** Compute execution waves using topological sort. */
export function computeWaves(tasks) {
    const graph = buildDependencyGraph(tasks);
    const waves = [];
    const completed = new Set();
    for (const task of tasks) {
        if (task.status === 'done' || task.status === 'cancelled') {
            completed.add(task.id);
        }
    }
    let remaining = tasks.filter((t) => t.status !== 'done' && t.status !== 'cancelled');
    let waveNumber = 1;
    const maxWaves = 50;
    while (remaining.length > 0 && waveNumber <= maxWaves) {
        const waveTasks = remaining.filter((t) => {
            const deps = graph.get(t.id) || new Set();
            return Array.from(deps).every((d) => completed.has(d));
        });
        if (waveTasks.length === 0)
            break;
        waves.push({
            waveNumber,
            tasks: waveTasks.map((t) => t.id),
            status: waveTasks.every((t) => completed.has(t.id))
                ? 'completed'
                : waveTasks.some((t) => t.status === 'active')
                    ? 'in_progress'
                    : 'pending',
        });
        for (const t of waveTasks) {
            completed.add(t.id);
        }
        remaining = remaining.filter((t) => !waveTasks.some((wt) => wt.id === t.id));
        waveNumber++;
    }
    if (remaining.length > 0) {
        waves.push({
            waveNumber,
            tasks: remaining.map((t) => t.id),
            status: 'pending',
        });
    }
    return waves;
}
/** Get enriched wave data for an epic. */
export async function getEnrichedWaves(epicId, cwd, accessor) {
    const acc = accessor ?? (await getAccessor(cwd));
    const children = await acc.getChildren(epicId);
    const waves = computeWaves(children);
    const taskMap = new Map(children.map((t) => [t.id, t]));
    const enrichedWaves = waves.map((w) => ({
        ...w,
        tasks: w.tasks.map((id) => ({
            id,
            title: taskMap.get(id)?.title || id,
            status: taskMap.get(id)?.status || 'unknown',
        })),
    }));
    return {
        epicId,
        waves: enrichedWaves,
        totalWaves: waves.length,
        totalTasks: children.length,
    };
}
//# sourceMappingURL=waves.js.map