import a from '../chunks/index5.mjs';

class ExecutionTracer {
  traces = /* @__PURE__ */ new Map();
  currentSessionId = null;
  /**
   * Start a new trace session
   */
  startSession(sessionId) {
    this.currentSessionId = sessionId;
    this.traces.set(sessionId, {
      sessionId,
      startTime: Date.now(),
      events: [],
      metadata: {
        totalEvents: 0,
        totalDuration: 0,
        agentCount: 0,
        toolCallCount: 0,
        errorCount: 0
      }
    });
  }
  /**
   * End current trace session
   */
  endSession(sessionId) {
    const sid = sessionId || this.currentSessionId;
    if (!sid)
      return;
    const trace = this.traces.get(sid);
    if (trace) {
      trace.endTime = Date.now();
      trace.metadata.totalDuration = trace.endTime - trace.startTime;
    }
    if (sid === this.currentSessionId) {
      this.currentSessionId = null;
    }
  }
  /**
   * Log an event
   */
  logEvent(type, data, options) {
    const sessionId = options?.sessionId || this.currentSessionId;
    if (!sessionId) {
      throw new Error("No active trace session");
    }
    const trace = this.traces.get(sessionId);
    if (!trace) {
      throw new Error(`Trace session not found: ${sessionId}`);
    }
    const eventId = `${sessionId}-${trace.events.length}`;
    const event = {
      id: eventId,
      sessionId,
      timestamp: Date.now(),
      type,
      agentId: options?.agentId,
      data,
      duration: options?.duration,
      parentId: options?.parentId
    };
    trace.events.push(event);
    trace.metadata.totalEvents++;
    if (type === "agent-start") {
      trace.metadata.agentCount++;
    } else if (type === "tool-call") {
      trace.metadata.toolCallCount++;
    } else if (type === "error") {
      trace.metadata.errorCount++;
    }
    return eventId;
  }
  /**
   * Log agent start
   */
  logAgentStart(agentId, data = {}) {
    return this.logEvent("agent-start", { agentId, ...data }, { agentId });
  }
  /**
   * Log agent end
   */
  logAgentEnd(agentId, data = {}, duration) {
    return this.logEvent("agent-end", { agentId, ...data }, { agentId, duration });
  }
  /**
   * Log decision
   */
  logDecision(agentId, decision, reasoning) {
    return this.logEvent("decision", { decision, reasoning }, { agentId });
  }
  /**
   * Log tool call
   */
  logToolCall(tool, args, agentId) {
    return this.logEvent("tool-call", { tool, args }, { agentId });
  }
  /**
   * Log tool result
   */
  logToolResult(tool, result, duration, parentId) {
    return this.logEvent("tool-result", { tool, result }, { duration, parentId });
  }
  /**
   * Log error
   */
  logError(error, agentId) {
    return this.logEvent("error", {
      message: error.message,
      stack: error.stack
    }, { agentId });
  }
  /**
   * Get trace for session
   */
  getTrace(sessionId) {
    return this.traces.get(sessionId);
  }
  /**
   * List all traces
   */
  listTraces() {
    return Array.from(this.traces.values());
  }
  /**
   * Clear old traces (keep last N)
   */
  cleanup(keepLast = 10) {
    const traces = this.listTraces().sort((a, b) => b.startTime - a.startTime);
    const toKeep = new Set(traces.slice(0, keepLast).map((t) => t.sessionId));
    for (const [sessionId] of this.traces) {
      if (!toKeep.has(sessionId)) {
        this.traces.delete(sessionId);
      }
    }
  }
  /**
   * Visualize trace as ASCII tree
   */
  visualizeTrace(sessionId) {
    const trace = this.traces.get(sessionId);
    if (!trace) {
      return a.red(`Trace not found: ${sessionId}`);
    }
    const lines = [];
    lines.push(a.cyan.bold(`
\u{1F4CA} Execution Trace: ${sessionId}`));
    lines.push(a.gray(`Started: ${new Date(trace.startTime).toISOString()}`));
    if (trace.endTime) {
      lines.push(a.gray(`Duration: ${trace.endTime - trace.startTime}ms`));
    }
    lines.push(a.gray(`Events: ${trace.metadata.totalEvents}`));
    lines.push("");
    const agentEvents = /* @__PURE__ */ new Map();
    for (const event of trace.events) {
      const agentId = event.agentId || "system";
      if (!agentEvents.has(agentId)) {
        agentEvents.set(agentId, []);
      }
      agentEvents.get(agentId).push(event);
    }
    for (const [agentId, events] of agentEvents) {
      lines.push(a.yellow(`\u{1F916} ${agentId}`));
      for (const event of events) {
        const time = new Date(event.timestamp).toLocaleTimeString();
        const icon = this.getEventIcon(event.type);
        const color = this.getEventColor(event.type);
        let line = `  ${icon} ${time} ${color(event.type)}`;
        if (event.type === "decision") {
          line += `: ${event.data.decision}`;
        } else if (event.type === "tool-call") {
          line += `: ${event.data.tool}(${JSON.stringify(event.data.args).slice(0, 50)}...)`;
        } else if (event.type === "tool-result" && event.duration) {
          line += `: ${event.data.tool} (${event.duration}ms)`;
        } else if (event.type === "error") {
          line += `: ${event.data.message}`;
        }
        lines.push(line);
      }
      lines.push("");
    }
    lines.push(a.cyan("\u{1F4C8} Summary"));
    lines.push(`  Agents: ${trace.metadata.agentCount}`);
    lines.push(`  Tool Calls: ${trace.metadata.toolCallCount}`);
    lines.push(`  Errors: ${trace.metadata.errorCount}`);
    lines.push("");
    return lines.join("\n");
  }
  /**
   * Get icon for event type
   */
  getEventIcon(type) {
    const icons = {
      "agent-start": "\u25B6\uFE0F",
      "agent-end": "\u23F9\uFE0F",
      "decision": "\u{1F9E0}",
      "tool-call": "\u{1F527}",
      "tool-result": "\u2705",
      "error": "\u274C",
      "context-load": "\u{1F4E5}",
      "context-save": "\u{1F4E4}"
    };
    return icons[type] || "\u2022";
  }
  /**
   * Get color function for event type
   */
  getEventColor(type) {
    const colors = {
      "agent-start": a.green,
      "agent-end": a.gray,
      "decision": a.cyan,
      "tool-call": a.blue,
      "tool-result": a.green,
      "error": a.red,
      "context-load": a.yellow,
      "context-save": a.yellow
    };
    return colors[type] || a.white;
  }
}
const executionTracer = new ExecutionTracer();

export { executionTracer as e };
