// orchestrator/task-distributor.ts — Task distribution engine (SPEC-079 AC-04)
// Matches tasks to agents based on capabilities and file ownership.
/**
 * Score how well an agent matches a task's requirements.
 * Higher score = better match.
 */
function scoreAgentForTask(agent, task) {
    let score = 0;
    // Capability matching: +2 per matching requirement
    for (const req of task.requirements) {
        const reqLower = req.toLowerCase();
        for (const cap of agent.capabilities) {
            if (cap.toLowerCase().includes(reqLower) || reqLower.includes(cap.toLowerCase())) {
                score += 2;
                break;
            }
        }
    }
    // File pattern matching: +1 per overlapping file
    for (const file of task.files) {
        for (const cap of agent.capabilities) {
            if (file.includes(cap) || cap.includes(file)) {
                score += 1;
                break;
            }
        }
    }
    // Base score if agent has any capabilities matching
    if (score === 0 && agent.capabilities.length > 0) {
        score = 1; // fallback: at least give a base score
    }
    return score;
}
/**
 * Distribute tasks among available agents.
 * Uses capability matching and ensures no file ownership conflicts.
 * Tasks with dependencies are assigned but their dependency list is preserved.
 */
export function distributeTasks(tasks, agents) {
    if (agents.length === 0 || tasks.length === 0) {
        return [];
    }
    // Sort tasks by priority (higher first) then by criticality
    const sorted = [...tasks].sort((a, b) => {
        if (a.critical !== b.critical) {
            return a.critical ? -1 : 1;
        }
        return b.priority - a.priority;
    });
    const assignments = [];
    const fileOwnership = new Map();
    for (const task of sorted) {
        const bestAgent = findBestAgent(task, agents, fileOwnership);
        if (!bestAgent) {
            continue;
        }
        // Assign files to this agent
        for (const file of task.files) {
            if (!fileOwnership.has(file)) {
                fileOwnership.set(file, bestAgent.id);
            }
        }
        assignments.push({
            taskId: task.id,
            agentId: bestAgent.id,
            files: task.files,
            context: `Task: ${task.description}`,
            priority: task.priority,
            dependencies: task.dependencies,
        });
    }
    return assignments;
}
/**
 * Find the best agent for a task, avoiding file ownership conflicts.
 */
function findBestAgent(task, agents, fileOwnership) {
    const scored = agents
        .map((agent) => ({
        agent,
        score: scoreAgentForTask(agent, task),
        conflicts: countFileConflicts(task, agent, fileOwnership),
    }))
        .sort((a, b) => {
        // Prefer fewer conflicts, then higher score
        if (a.conflicts !== b.conflicts) {
            return a.conflicts - b.conflicts;
        }
        return b.score - a.score;
    });
    return scored[0]?.agent;
}
/**
 * Count how many files in a task are already owned by a different agent.
 */
function countFileConflicts(task, agent, fileOwnership) {
    let conflicts = 0;
    for (const file of task.files) {
        const owner = fileOwnership.get(file);
        if (owner !== undefined && owner !== agent.id) {
            conflicts++;
        }
    }
    return conflicts;
}
//# sourceMappingURL=task-distributor.js.map