import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { EventEmitter } from "events";
import { logger } from "../../../core/monitoring/logger.js";
class EnhancedCoordinationSystem extends EventEmitter {
  agents = /* @__PURE__ */ new Map();
  messageQueue = [];
  dependencies = /* @__PURE__ */ new Map();
  conflicts = /* @__PURE__ */ new Map();
  coordinationRules = [];
  constructor() {
    super();
    this.setupDefaultRules();
  }
  /**
   * Register an agent with the coordination system
   */
  registerAgent(agent) {
    this.agents.set(agent.id, agent);
    logger.info(`Agent ${agent.role} registered for coordination`);
    this.broadcastMessage({
      id: this.generateId(),
      from: "system",
      to: "broadcast",
      type: "status_update",
      content: { type: "agent_joined", agent: agent.role },
      timestamp: Date.now(),
      priority: "normal"
    });
  }
  /**
   * Send message between agents
   */
  sendMessage(message) {
    const fullMessage = {
      ...message,
      id: this.generateId(),
      timestamp: Date.now()
    };
    this.messageQueue.push(fullMessage);
    this.routeMessage(fullMessage);
    this.emit("messageReceived", fullMessage);
  }
  /**
   * Broadcast message to all agents
   */
  broadcastMessage(message) {
    this.sendMessage({
      ...message,
      to: "broadcast"
    });
  }
  /**
   * Request help from other agents
   */
  requestHelp(fromAgent, helpType, context) {
    const suitableAgents = this.findSuitableHelpers(helpType);
    this.sendMessage({
      from: fromAgent,
      to: suitableAgents,
      type: "help_request",
      content: {
        helpType,
        context,
        requesterCapabilities: this.agents.get(fromAgent)?.capabilities || []
      },
      priority: "high"
    });
  }
  /**
   * Add task dependency
   */
  addDependency(dependency) {
    this.dependencies.set(dependency.taskId, dependency);
    this.updateCriticalPath();
    logger.info(
      `Added dependency: ${dependency.taskId} depends on ${dependency.dependsOn.join(", ")}`
    );
  }
  /**
   * Resolve conflicts automatically
   */
  async resolveConflict(conflictId) {
    const conflict = this.conflicts.get(conflictId);
    if (!conflict) return false;
    try {
      switch (conflict.resolutionStrategy) {
        case "voting":
          conflict.resolution = await this.resolveByVoting(conflict);
          break;
        case "expertise_based":
          conflict.resolution = await this.resolveByExpertise(conflict);
          break;
        case "random":
          conflict.resolution = await this.resolveRandomly(conflict);
          break;
        case "manager_override":
          conflict.resolution = await this.resolveByManagerOverride(conflict);
          break;
      }
      conflict.status = "resolved";
      this.conflicts.set(conflictId, conflict);
      this.broadcastMessage({
        from: "system",
        to: conflict.involvedAgents,
        type: "status_update",
        content: {
          type: "conflict_resolved",
          conflictId,
          resolution: conflict.resolution
        },
        priority: "high"
      });
      return true;
    } catch (error) {
      conflict.status = "escalated";
      logger.error(`Failed to resolve conflict ${conflictId}:`, error);
      return false;
    }
  }
  /**
   * Get optimal task execution order considering dependencies
   */
  getOptimalExecutionOrder(tasks) {
    const graph = this.buildDependencyGraph(tasks);
    return this.topologicalSort(graph, tasks);
  }
  /**
   * Detect and report coordination patterns
   */
  analyzeCoordinationPatterns() {
    const patterns = {
      communicationFrequency: /* @__PURE__ */ new Map(),
      helpRequestPatterns: [],
      conflictFrequency: /* @__PURE__ */ new Map(),
      bottlenecks: this.identifyBottlenecks()
    };
    for (const message of this.messageQueue) {
      const key = `${message.from}-${message.type}`;
      patterns.communicationFrequency.set(
        key,
        (patterns.communicationFrequency.get(key) || 0) + 1
      );
    }
    for (const conflict of this.conflicts.values()) {
      patterns.conflictFrequency.set(
        conflict.type,
        (patterns.conflictFrequency.get(conflict.type) || 0) + 1
      );
    }
    return patterns;
  }
  /**
   * Load balancing recommendations
   */
  getLoadBalancingRecommendations() {
    const recommendations = {
      overloadedAgents: [],
      underutilizedAgents: [],
      suggestedReassignments: []
    };
    for (const agent of this.agents.values()) {
      const workload = this.calculateAgentWorkload(agent);
      if (workload > 0.8) {
        recommendations.overloadedAgents.push(agent.id);
      } else if (workload < 0.3) {
        recommendations.underutilizedAgents.push(agent.id);
      }
    }
    for (const overloaded of recommendations.overloadedAgents) {
      for (const underutilized of recommendations.underutilizedAgents) {
        const compatibility = this.checkAgentCompatibility(
          overloaded,
          underutilized
        );
        if (compatibility.score > 0.7) {
          recommendations.suggestedReassignments.push({
            fromAgent: overloaded,
            toAgent: underutilized,
            taskType: compatibility.bestTaskType,
            reason: `Load balancing: ${compatibility.reason}`
          });
        }
      }
    }
    return recommendations;
  }
  routeMessage(message) {
    if (message.to === "broadcast") {
      for (const agentId of this.agents.keys()) {
        if (agentId !== message.from) {
          this.deliverMessage(agentId, message);
        }
      }
    } else {
      for (const agentId of message.to) {
        this.deliverMessage(agentId, message);
      }
    }
    this.applyCoordinationRules(message);
  }
  deliverMessage(agentId, message) {
    const agent = this.agents.get(agentId);
    if (agent) {
      logger.debug(`Message delivered to ${agent.role}: ${message.type}`);
    }
  }
  findSuitableHelpers(helpType) {
    const helpers = [];
    for (const agent of this.agents.values()) {
      if (this.canProvideHelp(agent, helpType)) {
        helpers.push(agent.id);
      }
    }
    return helpers;
  }
  canProvideHelp(agent, helpType) {
    const capabilities = agent.capabilities || [];
    switch (helpType) {
      case "code_review":
        return capabilities.includes("code_review") || agent.role === "reviewer";
      case "debugging":
        return capabilities.includes("debugging") || agent.role === "developer";
      case "testing":
        return capabilities.includes("testing") || agent.role === "tester";
      case "optimization":
        return capabilities.includes("optimization") || agent.role === "optimizer";
      default:
        return false;
    }
  }
  async resolveByVoting(conflict) {
    const votes = /* @__PURE__ */ new Map();
    for (const agentId of conflict.involvedAgents) {
      const agent = this.agents.get(agentId);
      if (agent) {
        votes.set(agentId, Math.random() > 0.5 ? "option_a" : "option_b");
      }
    }
    const results = /* @__PURE__ */ new Map();
    for (const vote of votes.values()) {
      results.set(vote, (results.get(vote) || 0) + 1);
    }
    return Array.from(results.entries()).reduce(
      (a, b) => a[1] > b[1] ? a : b
    )[0];
  }
  async resolveByExpertise(conflict) {
    let bestAgent = null;
    let bestExpertise = 0;
    for (const agentId of conflict.involvedAgents) {
      const agent = this.agents.get(agentId);
      if (agent) {
        const expertise = this.calculateExpertise(agent, conflict.type);
        if (expertise > bestExpertise) {
          bestExpertise = expertise;
          bestAgent = agent;
        }
      }
    }
    return {
      resolutionSource: bestAgent?.id,
      method: "expertise_based",
      expertiseScore: bestExpertise
    };
  }
  async resolveRandomly(conflict) {
    const options = ["option_a", "option_b", "compromise"];
    return options[Math.floor(Math.random() * options.length)];
  }
  async resolveByManagerOverride(conflict) {
    const manager = Array.from(this.agents.values()).find(
      (agent) => agent.role === "coordinator" || agent.role === "architect"
    );
    return {
      resolutionSource: manager?.id || "system",
      method: "manager_override"
    };
  }
  calculateExpertise(agent, conflictType) {
    const capabilities = agent.capabilities || [];
    const performance = agent.performance;
    let expertise = 0;
    switch (conflictType) {
      case "resource":
        expertise += capabilities.includes("resource_optimization") ? 0.5 : 0;
        break;
      case "task_overlap":
        expertise += capabilities.includes("coordination") ? 0.5 : 0;
        break;
    }
    if (performance) {
      expertise += performance.successRate * 0.3;
      expertise += Math.min(performance.tasksCompleted / 10, 0.2);
    }
    return Math.min(expertise, 1);
  }
  buildDependencyGraph(tasks) {
    const graph = /* @__PURE__ */ new Map();
    for (const task of tasks) {
      const deps = this.dependencies.get(task.id);
      graph.set(task.id, deps?.dependsOn || []);
    }
    return graph;
  }
  topologicalSort(graph, tasks) {
    const result = [];
    const visited = /* @__PURE__ */ new Set();
    const visiting = /* @__PURE__ */ new Set();
    const visit = (taskId) => {
      if (visited.has(taskId)) return;
      if (visiting.has(taskId)) {
        logger.warn(`Circular dependency detected involving task: ${taskId}`);
        return;
      }
      visiting.add(taskId);
      const deps = graph.get(taskId) || [];
      for (const dep of deps) {
        visit(dep);
      }
      visiting.delete(taskId);
      visited.add(taskId);
      const task = tasks.find((t) => t.id === taskId);
      if (task) result.push(task);
    };
    for (const task of tasks) {
      visit(task.id);
    }
    return result;
  }
  updateCriticalPath() {
    logger.debug("Critical path updated");
  }
  identifyBottlenecks() {
    const bottlenecks = [];
    for (const [taskId, dep] of this.dependencies) {
      if (dep.blockingFor.length > 2) {
        bottlenecks.push(taskId);
      }
    }
    return bottlenecks;
  }
  calculateAgentWorkload(agent) {
    let workload = 0;
    if (agent.status === "active") workload += 0.5;
    if (agent.currentTask) workload += 0.3;
    const recentMessages = this.messageQueue.filter(
      (m) => (m.from === agent.id || Array.isArray(m.to) && m.to.includes(agent.id)) && Date.now() - m.timestamp < 3e5
      // 5 minutes
    );
    workload += Math.min(recentMessages.length * 0.05, 0.2);
    return Math.min(workload, 1);
  }
  checkAgentCompatibility(agent1Id, agent2Id) {
    const agent1 = this.agents.get(agent1Id);
    const agent2 = this.agents.get(agent2Id);
    if (!agent1 || !agent2) {
      return { score: 0, bestTaskType: "", reason: "Agent not found" };
    }
    const caps1 = new Set(agent1.capabilities || []);
    const caps2 = new Set(agent2.capabilities || []);
    const overlap = new Set([...caps1].filter((x) => caps2.has(x)));
    const score = overlap.size / Math.max(caps1.size, caps2.size, 1);
    return {
      score,
      bestTaskType: Array.from(overlap)[0] || "general",
      reason: `Capability overlap: ${overlap.size} common skills`
    };
  }
  applyCoordinationRules(message) {
    for (const rule of this.coordinationRules) {
      if (rule.condition(message)) {
        rule.action(message, this);
      }
    }
  }
  setupDefaultRules() {
    this.coordinationRules = [
      {
        id: "help_request_timeout",
        condition: (msg) => msg.type === "help_request",
        action: (msg, system) => {
          setTimeout(() => {
            system.broadcastMessage({
              from: "system",
              to: "broadcast",
              type: "status_update",
              content: {
                type: "help_request_timeout",
                originalRequest: msg.id
              },
              priority: "urgent"
            });
          }, 3e5);
        }
      }
    ];
  }
  generateId() {
    return `coord_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }
}
var enhanced_coordination_default = EnhancedCoordinationSystem;
export {
  EnhancedCoordinationSystem,
  enhanced_coordination_default as default
};
//# sourceMappingURL=enhanced-coordination.js.map
