import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import blessed from "blessed";
import { logger } from "../../core/monitoring/logger.js";
import { SwarmDashboard } from "../../integrations/ralph/monitoring/swarm-dashboard.js";
import { SwarmRegistry } from "../../integrations/ralph/monitoring/swarm-registry.js";
import { execSync } from "child_process";
class SwarmTUI {
  screen;
  commitsTable;
  statusBox;
  agentsTable;
  metricsBox;
  logBox;
  swarmCoordinator = null;
  swarmDashboard = null;
  refreshInterval = null;
  commitMetrics = /* @__PURE__ */ new Map();
  constructor() {
    const isGhostty = process.env.TERM_PROGRAM === "ghostty" || process.env.TERM?.includes("ghostty");
    const isBasicTerm = process.env.TERM === "dumb" || process.env.TERM === "unknown";
    this.screen = blessed.screen({
      smartCSR: !isGhostty,
      // Disable smart CSR for ghostty
      title: "Ralph Swarm Monitor",
      terminal: isGhostty ? "xterm-256color" : void 0,
      fullUnicode: !isBasicTerm,
      dockBorders: false,
      ignoreDockContrast: true,
      useBCE: false,
      // Disable background color erase for compatibility
      forceUnicode: false,
      debug: false
    });
    this.screen.on("error", (err) => {
      logger.error("TUI screen error:", err);
      console.log(
        "\u26A0\uFE0F  TUI display error detected. Try setting TERM=xterm-256color"
      );
      console.log(
        "   Alternative: Use stackmemory ralph status for text-based monitoring"
      );
    });
    this.createUI();
    this.setupKeyHandlers();
    logger.info("SwarmTUI initialized");
  }
  createUI() {
    const container = blessed.box({
      parent: this.screen,
      top: 0,
      left: 0,
      width: "100%",
      height: "100%",
      style: {
        bg: "black"
      }
    });
    const isGhostty = process.env.TERM_PROGRAM === "ghostty" || process.env.TERM?.includes("ghostty");
    const safeColors = isGhostty;
    blessed.box({
      parent: container,
      top: 0,
      left: 0,
      width: "100%",
      height: 3,
      content: "\u{1F9BE} Ralph Swarm Monitor - Real-time Swarm Operations",
      style: safeColors ? {
        fg: "white",
        bold: false
      } : {
        bg: "blue",
        fg: "white",
        bold: true
      },
      border: {
        type: "line"
      }
    });
    this.statusBox = blessed.box({
      parent: container,
      top: 3,
      left: "50%",
      width: "50%",
      height: 8,
      label: " Swarm Status ",
      content: "No active swarm",
      style: {
        bg: "black",
        fg: "white"
      },
      border: {
        type: "line",
        fg: "cyan"
      }
    });
    this.metricsBox = blessed.box({
      parent: container,
      top: 3,
      left: 0,
      width: "50%",
      height: 8,
      label: " Performance Metrics ",
      content: "Waiting for data...",
      style: {
        bg: "black",
        fg: "white"
      },
      border: {
        type: "line",
        fg: "green"
      }
    });
    this.agentsTable = blessed.table({
      parent: container,
      top: 11,
      left: 0,
      width: "50%",
      height: 12,
      label: " Active Agents ",
      style: {
        bg: "black",
        fg: "white",
        header: {
          bg: "blue",
          fg: "white",
          bold: true
        },
        cell: {
          selected: {
            bg: "blue",
            fg: "white"
          }
        }
      },
      border: {
        type: "line",
        fg: "yellow"
      },
      data: [["Role", "Status", "Iteration", "Task", "Last Active"]]
    });
    this.commitsTable = blessed.table({
      parent: container,
      top: 11,
      left: "50%",
      width: "50%",
      height: 12,
      label: " Recent Commits ",
      style: {
        bg: "black",
        fg: "white",
        header: {
          bg: "blue",
          fg: "white",
          bold: true
        },
        cell: {
          selected: {
            bg: "blue",
            fg: "white"
          }
        }
      },
      border: {
        type: "line",
        fg: "magenta"
      },
      data: [["Agent", "Message", "Lines +/-", "Time"]]
    });
    this.logBox = blessed.log({
      parent: container,
      top: 23,
      left: 0,
      width: "100%",
      height: "100%-23",
      label: " Swarm Logs ",
      style: {
        bg: "black",
        fg: "white"
      },
      border: {
        type: "line",
        fg: "white"
      },
      scrollable: true,
      alwaysScroll: true,
      mouse: true
    });
    blessed.box({
      parent: container,
      bottom: 0,
      left: 0,
      width: "100%",
      height: 1,
      content: "q=quit | r=refresh | s=start swarm | t=stop swarm | h=help | c=clear logs | d=detect swarms",
      style: {
        bg: "white",
        fg: "black"
      }
    });
  }
  setupKeyHandlers() {
    this.screen.key(["escape", "q", "C-c"], () => {
      this.cleanup();
      process.exit(0);
    });
    this.screen.key(["r"], () => {
      this.refreshData();
      this.logBox.log("Manual refresh triggered");
    });
    this.screen.key(["s"], () => {
      this.startSwarmInteractive();
    });
    this.screen.key(["t"], () => {
      this.stopSwarmInteractive();
    });
    this.screen.key(["h"], () => {
      this.showHelp();
    });
    this.screen.key(["c"], () => {
      this.clearLogs();
    });
    this.screen.key(["d"], () => {
      this.showDetectedSwarms();
    });
  }
  /**
   * Initialize swarm monitoring
   */
  async initialize(swarmCoordinator, swarmId) {
    try {
      if (swarmId) {
        const registry = SwarmRegistry.getInstance();
        const swarm = registry.getSwarm(swarmId);
        if (swarm) {
          this.swarmCoordinator = swarm.coordinator;
          this.logBox.log(`Connected to swarm: ${swarmId}`);
        } else {
          this.logBox.log(`Swarm not found: ${swarmId}`);
        }
      } else if (swarmCoordinator) {
        this.swarmCoordinator = swarmCoordinator;
      } else {
        const registry = SwarmRegistry.getInstance();
        const activeSwarms = registry.listActiveSwarms();
        if (activeSwarms.length > 0) {
          this.swarmCoordinator = activeSwarms[0].coordinator;
          this.logBox.log(`Auto-connected to swarm: ${activeSwarms[0].id}`);
        }
      }
      if (this.swarmCoordinator) {
        this.swarmDashboard = new SwarmDashboard(this.swarmCoordinator);
        this.swarmDashboard.startMonitoring(2e3);
        this.swarmDashboard.on("metricsUpdated", (metrics) => {
          this.updateUI(metrics);
        });
      }
      this.refreshInterval = setInterval(() => {
        this.refreshData();
      }, 3e3);
      this.logBox.log("SwarmTUI monitoring initialized");
    } catch (error) {
      logger.error("Failed to initialize SwarmTUI", error);
      this.logBox.log(`Error: ${error.message}`);
    }
  }
  /**
   * Start the TUI display
   */
  start() {
    this.screen.render();
    this.logBox.log("Ralph Swarm Monitor started");
    this.logBox.log("Monitoring for active swarms...");
  }
  /**
   * Refresh all data
   */
  async refreshData() {
    try {
      await this.updateCommitMetrics();
      if (this.swarmCoordinator) {
        const status = this.getSwarmStatus();
        this.updateStatusDisplay(status);
      } else {
        await this.detectActiveSwarms();
      }
      this.screen.render();
    } catch (error) {
      logger.error("Failed to refresh TUI data", error);
      this.logBox.log(`Refresh error: ${error.message}`);
    }
  }
  /**
   * Update commit metrics for all agents
   */
  async updateCommitMetrics() {
    try {
      const gitLog = execSync(
        'git log --oneline --since="1 hour ago" --pretty=format:"%H|%an|%s|%ct" --numstat',
        { encoding: "utf8", cwd: process.cwd() }
      );
      const commits = this.parseGitCommits(gitLog);
      this.updateCommitsTable(commits);
    } catch {
      this.logBox.log("No recent commits found");
    }
  }
  /**
   * Parse git log output into commit data
   */
  parseGitCommits(gitLog) {
    const commits = [];
    const lines = gitLog.split("\n").filter(Boolean);
    let currentCommit = null;
    for (const line of lines) {
      if (line.includes("|")) {
        const [hash, author, message, timestamp] = line.split("|");
        currentCommit = {
          hash: hash.substring(0, 8),
          agent: this.extractAgentFromAuthor(author),
          message: message.substring(0, 50),
          timestamp: parseInt(timestamp),
          linesAdded: 0,
          linesDeleted: 0
        };
      } else if (currentCommit && line.match(/^\d+\s+\d+/)) {
        const [added, deleted] = line.split("	")[0].split(" ");
        currentCommit.linesAdded += parseInt(added) || 0;
        currentCommit.linesDeleted += parseInt(deleted) || 0;
        commits.push({ ...currentCommit });
        currentCommit = null;
      }
    }
    return commits.slice(0, 10);
  }
  /**
   * Extract agent info from git author
   */
  extractAgentFromAuthor(author) {
    const agentMatch = author.match(/\[(\w+)\]/);
    if (agentMatch) {
      return agentMatch[1];
    }
    const roles = [
      "developer",
      "tester",
      "optimizer",
      "documenter",
      "architect"
    ];
    for (const role of roles) {
      if (author.toLowerCase().includes(role)) {
        return role;
      }
    }
    return "user";
  }
  /**
   * Update commits table display
   */
  updateCommitsTable(commits) {
    const tableData = [["Agent", "Message", "Lines +/-", "Time"]];
    for (const commit of commits) {
      const timeAgo = this.formatTimeAgo(commit.timestamp * 1e3);
      const linesChange = `+${commit.linesAdded}/-${commit.linesDeleted}`;
      tableData.push([commit.agent, commit.message, linesChange, timeAgo]);
    }
    this.commitsTable.setData(tableData);
  }
  /**
   * Get current swarm status
   */
  getSwarmStatus() {
    if (!this.swarmCoordinator) return null;
    const usage = this.swarmCoordinator.getResourceUsage();
    const swarmState = this.swarmCoordinator.swarmState;
    if (!swarmState) return null;
    return {
      swarmId: swarmState.id,
      status: swarmState.status,
      startTime: swarmState.startTime,
      uptime: Date.now() - swarmState.startTime,
      agents: usage.activeAgents ? Array.from(
        this.swarmCoordinator.activeAgents?.values() || []
      ).map((agent) => ({
        id: agent.id,
        role: agent.role,
        status: agent.status,
        currentTask: agent.currentTask,
        iteration: agent.performance?.tasksCompleted || 0,
        lastActivity: agent.performance?.lastFreshStart || Date.now()
      })) : [],
      performance: {
        throughput: swarmState.performance?.throughput || 0,
        efficiency: swarmState.performance?.efficiency || 0,
        totalTasks: swarmState.totalTaskCount || 0,
        completedTasks: swarmState.completedTaskCount || 0
      }
    };
  }
  /**
   * Update status display
   */
  updateStatusDisplay(status) {
    if (!status) {
      this.statusBox.setContent("No active swarm detected");
      this.agentsTable.setData([
        ["Role", "Status", "Iteration", "Task", "Last Active"]
      ]);
      this.metricsBox.setContent("Waiting for swarm data...");
      return;
    }
    const uptimeStr = this.formatDuration(status.uptime);
    const statusContent = `Swarm: ${status.swarmId.substring(0, 8)}
Status: ${status.status.toUpperCase()}
Uptime: ${uptimeStr}
Agents: ${status.agents.length}`;
    this.statusBox.setContent(statusContent);
    const agentData = [["Role", "Status", "Iteration", "Task", "Last Active"]];
    for (const agent of status.agents) {
      const lastActivity = this.formatTimeAgo(agent.lastActivity);
      const task = agent.currentTask ? agent.currentTask.substring(0, 20) : "idle";
      agentData.push([
        agent.role,
        agent.status,
        agent.iteration.toString(),
        task,
        lastActivity
      ]);
    }
    this.agentsTable.setData(agentData);
    const metricsContent = `Throughput: ${status.performance.throughput.toFixed(2)} tasks/min
Efficiency: ${(status.performance.efficiency * 100).toFixed(1)}%
Tasks: ${status.performance.completedTasks}/${status.performance.totalTasks}
Success Rate: ${status.performance.efficiency > 0 ? (status.performance.efficiency * 100).toFixed(1) : "N/A"}%`;
    this.metricsBox.setContent(metricsContent);
  }
  /**
   * Update UI with metrics from dashboard
   */
  updateUI(metrics) {
    this.logBox.log(
      `Metrics updated: ${metrics.status} - ${metrics.activeAgents} agents`
    );
  }
  /**
   * Detect active swarms in the system
   */
  async detectActiveSwarms() {
    try {
      const registry = SwarmRegistry.getInstance();
      const activeSwarms = registry.listActiveSwarms();
      const stats = registry.getStatistics();
      if (activeSwarms.length > 0) {
        let statusContent = `Available Swarms (${activeSwarms.length}):
`;
        for (const swarm of activeSwarms.slice(0, 3)) {
          const uptime = this.formatDuration(Date.now() - swarm.startTime);
          statusContent += `\u2022 ${swarm.id.substring(0, 8)}: ${swarm.status} (${uptime})
`;
        }
        if (activeSwarms.length > 3) {
          statusContent += `... and ${activeSwarms.length - 3} more`;
        }
        this.statusBox.setContent(statusContent);
        this.logBox.log(
          `Found ${activeSwarms.length} active swarms in registry`
        );
      } else {
        const ralphProcesses = execSync(
          'ps aux | grep "ralph" | grep -v grep',
          { encoding: "utf8" }
        );
        if (ralphProcesses.trim()) {
          this.logBox.log("Detected Ralph processes running");
          this.statusBox.setContent(
            "External Ralph processes detected\n(Use swarm coordinator for full monitoring)"
          );
        } else {
          this.statusBox.setContent(`No active swarms detected
Total swarms: ${stats.totalSwarms}
Completed: ${stats.completedSwarms}

Run: stackmemory ralph swarm <task>`);
        }
      }
    } catch {
    }
  }
  /**
   * Format time ago string
   */
  formatTimeAgo(timestamp) {
    const diff = Date.now() - timestamp;
    const minutes = Math.floor(diff / 6e4);
    const hours = Math.floor(minutes / 60);
    const days = Math.floor(hours / 24);
    if (days > 0) return `${days}d ago`;
    if (hours > 0) return `${hours}h ago`;
    if (minutes > 0) return `${minutes}m ago`;
    return "just now";
  }
  /**
   * Format duration string
   */
  formatDuration(ms) {
    const seconds = Math.floor(ms / 1e3);
    const minutes = Math.floor(seconds / 60);
    const hours = Math.floor(minutes / 60);
    if (hours > 0) return `${hours}h ${minutes % 60}m`;
    if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
    return `${seconds}s`;
  }
  /**
   * Start swarm interactively
   */
  startSwarmInteractive() {
    this.logBox.log("\u{1F680} Start Swarm Interactive Mode:");
    this.logBox.log(
      'Example: stackmemory ralph swarm "Implement feature" --agents developer,tester'
    );
    this.logBox.log(
      'Tip: Run the command in another terminal, then press "d" to detect it'
    );
  }
  /**
   * Stop swarm interactively
   */
  stopSwarmInteractive() {
    if (this.swarmCoordinator) {
      this.logBox.log("\u{1F6D1} Stopping current swarm...");
      this.logBox.log(
        "Note: Swarm stopping not yet implemented - use Ctrl+C in swarm terminal"
      );
    } else {
      this.logBox.log("\u274C No active swarm coordinator to stop");
      this.logBox.log("External Ralph processes must be stopped manually");
    }
  }
  /**
   * Show help dialog
   */
  showHelp() {
    this.logBox.log("\u{1F9BE} Ralph Swarm Monitor - Help");
    this.logBox.log("");
    this.logBox.log("Keyboard Shortcuts:");
    this.logBox.log("  q, Esc, Ctrl+C - Quit TUI");
    this.logBox.log("  r - Refresh data manually");
    this.logBox.log("  s - Show start swarm commands");
    this.logBox.log("  t - Stop current swarm");
    this.logBox.log("  h - Show this help");
    this.logBox.log("  c - Clear log output");
    this.logBox.log("  d - Detect and list available swarms");
    this.logBox.log("");
    this.logBox.log("Usage:");
    this.logBox.log(
      "  stackmemory ralph tui                    # Auto-detect swarms"
    );
    this.logBox.log(
      "  stackmemory ralph tui --swarm-id <id>   # Monitor specific swarm"
    );
    this.logBox.log("");
    this.logBox.log("Starting Swarms:");
    this.logBox.log(
      '  stackmemory ralph swarm "Task description" --agents developer,tester'
    );
    this.logBox.log("");
  }
  /**
   * Clear log output
   */
  clearLogs() {
    this.logBox.setContent("");
    this.logBox.log("\u{1F4DD} Logs cleared - monitoring continues...");
  }
  /**
   * Show detected swarms
   */
  async showDetectedSwarms() {
    this.logBox.log("\u{1F50D} Detecting active swarms...");
    try {
      const registry = SwarmRegistry.getInstance();
      const activeSwarms = registry.listActiveSwarms();
      const stats = registry.getStatistics();
      this.logBox.log("");
      this.logBox.log("\u{1F4CA} Swarm Registry Status:");
      this.logBox.log(`   Total swarms: ${stats.totalSwarms}`);
      this.logBox.log(`   Active swarms: ${stats.activeSwarms}`);
      this.logBox.log(`   Completed swarms: ${stats.completedSwarms}`);
      if (activeSwarms.length > 0) {
        this.logBox.log("");
        this.logBox.log("\u{1F9BE} Active Swarms:");
        for (const swarm of activeSwarms) {
          const uptime = this.formatDuration(Date.now() - swarm.startTime);
          this.logBox.log(`   \u2022 ${swarm.id}: ${swarm.description} (${uptime})`);
        }
        this.logBox.log("");
        this.logBox.log("\u{1F4A1} Use --swarm-id to connect to specific swarm");
      } else {
        this.logBox.log("");
        this.logBox.log("\u274C No active swarms in registry");
        try {
          const ralphProcesses = execSync(
            'ps aux | grep "ralph" | grep -v grep',
            { encoding: "utf8" }
          );
          if (ralphProcesses.trim()) {
            this.logBox.log("\u{1F50D} External Ralph processes detected:");
            ralphProcesses.split("\n").filter((line) => line.trim()).forEach((line) => {
              const parts = line.split(/\s+/);
              this.logBox.log(
                `   PID ${parts[1]}: ${parts.slice(10).join(" ").slice(0, 60)}`
              );
            });
          }
        } catch {
          this.logBox.log("\u{1F50D} No external Ralph processes found");
        }
        this.logBox.log("");
        this.logBox.log(
          '\u{1F4A1} Start a swarm: stackmemory ralph swarm "Task" --agents developer'
        );
      }
    } catch (error) {
      this.logBox.log(`\u274C Detection failed: ${error.message}`);
    }
  }
  /**
   * Cleanup resources
   */
  cleanup() {
    if (this.refreshInterval) {
      clearInterval(this.refreshInterval);
    }
    if (this.swarmDashboard) {
      this.swarmDashboard.stopMonitoring();
    }
    logger.info("SwarmTUI cleaned up");
  }
}
var swarm_monitor_default = SwarmTUI;
export {
  SwarmTUI,
  swarm_monitor_default as default
};
//# sourceMappingURL=swarm-monitor.js.map
