/**
 * Dependency analysis for orchestration.
 *
 * Provides dependency graph building, circular dependency detection (DFS),
 * and missing dependency identification for epic task hierarchies.
 *
 * @task T5702
 */
/**
 * Build a dependency graph for a set of tasks.
 *
 * Returns a Map from task ID to the set of task IDs it depends on.
 */
export 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;
}
/**
 * Detect circular dependencies using DFS traversal.
 *
 * @param tasks - The set of tasks to analyze
 * @param graph - Pre-built dependency graph (optional; built from tasks if not provided)
 * @returns Array of circular dependency cycles (each cycle is an array of task IDs)
 */
export function detectCircularDependencies(tasks, graph) {
    const depGraph = graph ?? buildDependencyGraph(tasks);
    const circularDeps = [];
    const visited = new Set();
    const recursionStack = new Set();
    function dfs(taskId, path) {
        visited.add(taskId);
        recursionStack.add(taskId);
        const deps = depGraph.get(taskId) || new Set();
        for (const dep of deps) {
            if (!visited.has(dep)) {
                dfs(dep, [...path, taskId]);
            }
            else if (recursionStack.has(dep)) {
                circularDeps.push([...path, taskId, dep]);
            }
        }
        recursionStack.delete(taskId);
    }
    for (const task of tasks) {
        if (!visited.has(task.id)) {
            dfs(task.id, []);
        }
    }
    return circularDeps;
}
/**
 * Find missing dependencies — deps that reference tasks outside the epic
 * that are not yet completed.
 *
 * @param children - Child tasks of the epic
 * @param allTasks - All tasks in the project (to check if deps are completed elsewhere)
 * @returns Array of missing dependency references
 */
export function findMissingDependencies(children, allTasks) {
    const childIds = new Set(children.map((t) => t.id));
    const missingDeps = [];
    for (const task of children) {
        if (task.depends) {
            for (const dep of task.depends) {
                if (!childIds.has(dep) && !allTasks.find((t) => t.id === dep && t.status === 'done')) {
                    missingDeps.push({ taskId: task.id, missingDep: dep });
                }
            }
        }
    }
    return missingDeps;
}
/**
 * Perform full dependency analysis for an epic's children.
 *
 * Combines dependency graph building, circular detection, and missing dep
 * identification into a single analysis result.
 *
 * @param children - Child tasks of the epic
 * @param allTasks - All tasks in the project
 * @returns Complete dependency analysis
 */
export function analyzeDependencies(children, allTasks) {
    const graph = buildDependencyGraph(children);
    const circularDependencies = detectCircularDependencies(children, graph);
    const missingDependencies = findMissingDependencies(children, allTasks);
    const dependencyGraph = {};
    for (const [key, value] of graph.entries()) {
        dependencyGraph[key] = Array.from(value);
    }
    return {
        dependencyGraph,
        circularDependencies,
        missingDependencies,
    };
}
//# sourceMappingURL=analyze.js.map