import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import * as fs from "fs/promises";
import * as path from "path";
import { logger } from "../../../core/monitoring/logger.js";
import { FrameManager } from "../../../core/context/index.js";
import { sessionManager } from "../../../core/session/index.js";
class RalphDebugger {
  frameManager;
  activeSessions = /* @__PURE__ */ new Map();
  config;
  constructor(config) {
    this.config = {
      enableRealTimeMonitoring: true,
      captureDetailedTrace: true,
      generateVisualization: true,
      exportFormat: "html",
      maxTraceDepth: 50,
      ...config
    };
    logger.info("Ralph debugger initialized", this.config);
  }
  async initialize() {
    try {
      await sessionManager.initialize();
      const session = await sessionManager.getOrCreateSession({});
      if (session.database) {
        this.frameManager = new FrameManager(session.database, session.projectId);
      }
      logger.info("Debugger initialized successfully");
    } catch (error) {
      logger.error("Failed to initialize debugger", error);
      throw error;
    }
  }
  /**
   * Start debugging a Ralph loop
   */
  async startDebugSession(loopId, ralphDir) {
    logger.info("Starting debug session", { loopId, ralphDir });
    const session = {
      id: `debug-${Date.now()}`,
      loopId,
      ralphDir,
      startTime: Date.now(),
      iterations: [],
      contextFlow: [],
      performance: {
        iterationTimes: [],
        memoryUsage: [],
        contextSizes: [],
        averageIterationTime: 0,
        peakMemory: 0,
        contextEfficiency: 0
      },
      realTimeMonitoring: this.config.enableRealTimeMonitoring
    };
    this.activeSessions.set(loopId, session);
    if (this.config.enableRealTimeMonitoring) {
      await this.startRealTimeMonitoring(session);
    }
    return session;
  }
  /**
   * Generate comprehensive debug report
   */
  async generateDebugReport(loopId) {
    const session = this.activeSessions.get(loopId);
    if (!session) {
      throw new Error(`No debug session found for loop ${loopId}`);
    }
    logger.info("Generating debug report", { loopId });
    const report = {
      sessionId: session.id,
      loopId,
      generatedAt: Date.now(),
      summary: await this.generateSummary(session),
      iterationAnalysis: await this.analyzeIterations(session),
      contextAnalysis: await this.analyzeContextFlow(session),
      performanceAnalysis: await this.analyzePerformance(session),
      visualization: this.config.generateVisualization ? await this.generateVisualization(session) : void 0,
      recommendations: await this.generateRecommendations(session),
      exportPath: ""
    };
    const exportPath = await this.exportReport(report);
    report.exportPath = exportPath;
    logger.info("Debug report generated", { loopId, exportPath });
    return report;
  }
  /**
   * Create visual timeline of loop execution
   */
  async generateLoopTimeline(loopId) {
    const session = this.activeSessions.get(loopId);
    if (!session) {
      throw new Error(`No debug session found for loop ${loopId}`);
    }
    const timeline = {
      title: `Ralph Loop Timeline: ${loopId}`,
      startTime: session.startTime,
      iterations: session.iterations.map((iter) => ({
        iteration: iter.iteration,
        startTime: iter.startTime,
        endTime: iter.endTime,
        duration: iter.endTime - iter.startTime,
        success: iter.success,
        changes: iter.changes?.length || 0,
        errors: iter.errors?.length || 0,
        contextSize: iter.contextSize,
        phase: iter.phase
      })),
      totalDuration: session.performance.iterationTimes.reduce((sum, time) => sum + time, 0)
    };
    const html = await this.generateTimelineHTML(timeline);
    const timelinePath = path.join(".ralph-debug", `timeline-${loopId}.html`);
    await fs.mkdir(path.dirname(timelinePath), { recursive: true });
    await fs.writeFile(timelinePath, html);
    return timelinePath;
  }
  /**
   * Create context flow diagram
   */
  async generateContextFlowDiagram(loopId) {
    const session = this.activeSessions.get(loopId);
    if (!session) {
      throw new Error(`No debug session found for loop ${loopId}`);
    }
    const diagram = {
      id: `context-flow-${loopId}`,
      nodes: [],
      edges: [],
      metrics: {
        totalNodes: 0,
        totalEdges: 0,
        avgContextSize: 0,
        maxContextSize: 0
      }
    };
    for (let i = 0; i < session.iterations.length; i++) {
      const iteration = session.iterations[i];
      diagram.nodes.push({
        id: `iter-${iteration.iteration}`,
        type: "iteration",
        label: `Iteration ${iteration.iteration}`,
        size: iteration.contextSize || 100,
        color: iteration.success ? "#4CAF50" : "#F44336",
        metadata: {
          duration: iteration.endTime - iteration.startTime,
          changes: iteration.changes?.length || 0,
          errors: iteration.errors?.length || 0
        }
      });
      if (i < session.iterations.length - 1) {
        diagram.edges.push({
          id: `edge-${i}-${i + 1}`,
          from: `iter-${iteration.iteration}`,
          to: `iter-${session.iterations[i + 1].iteration}`,
          type: "sequence",
          weight: iteration.contextSize || 1
        });
      }
    }
    diagram.metrics = {
      totalNodes: diagram.nodes.length,
      totalEdges: diagram.edges.length,
      avgContextSize: session.performance.contextSizes.length > 0 ? session.performance.contextSizes.reduce((sum, size) => sum + size, 0) / session.performance.contextSizes.length : 0,
      maxContextSize: Math.max(...session.performance.contextSizes)
    };
    return diagram;
  }
  /**
   * Real-time monitoring of loop execution
   */
  async startRealTimeMonitoring(session) {
    const monitoringInterval = setInterval(async () => {
      try {
        await this.captureIterationTrace(session);
        await this.updatePerformanceMetrics(session);
      } catch (error) {
        logger.error("Monitoring error", error);
      }
    }, 1e3);
    session.monitoringInterval = monitoringInterval;
  }
  /**
   * Capture detailed trace of current iteration
   */
  async captureIterationTrace(session) {
    try {
      const statePath = path.join(session.ralphDir, "state.json");
      const iterationPath = path.join(session.ralphDir, "iteration.txt");
      let currentState = {};
      let currentIteration = 0;
      try {
        const stateData = await fs.readFile(statePath, "utf8");
        currentState = JSON.parse(stateData);
        const iterData = await fs.readFile(iterationPath, "utf8");
        currentIteration = parseInt(iterData.trim()) || 0;
      } catch {
        return;
      }
      const lastTrace = session.iterations[session.iterations.length - 1];
      if (lastTrace?.iteration === currentIteration) {
        return;
      }
      const trace = {
        iteration: currentIteration,
        startTime: Date.now(),
        endTime: Date.now(),
        // Will be updated when iteration completes
        phase: this.determineIterationPhase(session.ralphDir),
        contextSize: await this.calculateContextSize(session.ralphDir),
        success: false,
        // Will be updated
        changes: [],
        errors: [],
        memoryUsage: process.memoryUsage().heapUsed,
        stackTrace: this.captureStackTrace()
      };
      session.iterations.push(trace);
    } catch (error) {
      logger.debug("Failed to capture iteration trace", error);
    }
  }
  /**
   * Update performance metrics
   */
  async updatePerformanceMetrics(session) {
    const currentMemory = process.memoryUsage().heapUsed;
    session.performance.memoryUsage.push(currentMemory);
    session.performance.peakMemory = Math.max(session.performance.peakMemory, currentMemory);
    const contextSize = await this.calculateContextSize(session.ralphDir);
    session.performance.contextSizes.push(contextSize);
    if (session.performance.iterationTimes.length > 0) {
      session.performance.averageIterationTime = session.performance.iterationTimes.reduce((sum, time) => sum + time, 0) / session.performance.iterationTimes.length;
    }
    if (session.performance.contextSizes.length > 0) {
      const avgContextSize = session.performance.contextSizes.reduce((sum, size) => sum + size, 0) / session.performance.contextSizes.length;
      session.performance.contextEfficiency = Math.max(0, 1 - avgContextSize / 1e4);
    }
  }
  /**
   * Generate executive summary
   */
  async generateSummary(session) {
    const totalIterations = session.iterations.length;
    const successfulIterations = session.iterations.filter((i) => i.success).length;
    const totalDuration = session.performance.iterationTimes.reduce((sum, time) => sum + time, 0);
    return {
      loopId: session.loopId,
      totalIterations,
      successfulIterations,
      successRate: totalIterations > 0 ? successfulIterations / totalIterations : 0,
      totalDuration,
      averageIterationTime: session.performance.averageIterationTime,
      peakMemoryUsage: session.performance.peakMemory,
      contextEfficiency: session.performance.contextEfficiency,
      status: totalIterations > 0 && session.iterations[session.iterations.length - 1].success ? "completed" : "in_progress"
    };
  }
  /**
   * Analyze iteration patterns
   */
  async analyzeIterations(session) {
    if (session.iterations.length === 0) return { patterns: [], insights: [] };
    const patterns = [];
    const insights = [];
    const durations = session.iterations.map((i) => i.endTime - i.startTime);
    const avgDuration = durations.reduce((sum, d) => sum + d, 0) / durations.length;
    if (durations.some((d) => d > avgDuration * 2)) {
      patterns.push("Variable iteration times detected");
      insights.push("Some iterations took significantly longer than average - investigate bottlenecks");
    }
    const consecutiveFailures = this.findConsecutiveFailures(session.iterations);
    if (consecutiveFailures.length > 2) {
      patterns.push("Multiple consecutive failures detected");
      insights.push("Consider adjusting approach or criteria after consecutive failures");
    }
    if (session.performance.contextSizes.length > 1) {
      const contextGrowth = session.performance.contextSizes[session.performance.contextSizes.length - 1] - session.performance.contextSizes[0];
      if (contextGrowth > 1e3) {
        patterns.push("Significant context growth");
        insights.push("Context is growing rapidly - consider context pruning strategies");
      }
    }
    return { patterns, insights };
  }
  /**
   * Analyze context flow
   */
  async analyzeContextFlow(session) {
    return {
      avgContextSize: session.performance.contextSizes.length > 0 ? session.performance.contextSizes.reduce((sum, size) => sum + size, 0) / session.performance.contextSizes.length : 0,
      maxContextSize: Math.max(...session.performance.contextSizes),
      contextGrowthRate: this.calculateGrowthRate(session.performance.contextSizes),
      efficiency: session.performance.contextEfficiency
    };
  }
  /**
   * Analyze performance metrics
   */
  async analyzePerformance(session) {
    return {
      memoryEfficiency: this.calculateMemoryEfficiency(session.performance.memoryUsage),
      iterationEfficiency: session.performance.averageIterationTime,
      resourceUtilization: {
        cpu: "N/A",
        // Would need CPU monitoring
        memory: session.performance.peakMemory,
        context: session.performance.contextEfficiency
      }
    };
  }
  /**
   * Generate visualization HTML
   */
  async generateVisualization(session) {
    const htmlContent = await this.generateVisualizationHTML(session);
    const vizPath = path.join(".ralph-debug", `visualization-${session.loopId}.html`);
    await fs.mkdir(path.dirname(vizPath), { recursive: true });
    await fs.writeFile(vizPath, htmlContent);
    return {
      id: `viz-${session.loopId}`,
      type: "interactive_timeline",
      htmlPath: vizPath,
      data: {
        iterations: session.iterations,
        performance: session.performance,
        contextFlow: session.contextFlow
      },
      metadata: {
        generatedAt: Date.now(),
        format: "html",
        interactive: true
      }
    };
  }
  /**
   * Generate recommendations
   */
  async generateRecommendations(session) {
    const recommendations = [];
    if (session.performance.averageIterationTime > 3e4) {
      recommendations.push("Consider breaking down complex tasks into smaller iterations");
    }
    if (session.performance.contextEfficiency < 0.7) {
      recommendations.push("Optimize context management - consider using context budgeting");
    }
    const successRate = session.iterations.filter((i) => i.success).length / Math.max(1, session.iterations.length);
    if (successRate < 0.5) {
      recommendations.push("Low success rate detected - review task criteria and approach");
    }
    if (session.performance.peakMemory > 500 * 1024 * 1024) {
      recommendations.push("High memory usage detected - investigate memory leaks");
    }
    return recommendations;
  }
  /**
   * Export report in specified format
   */
  async exportReport(report) {
    const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
    const filename = `ralph-debug-${report.loopId}-${timestamp}`;
    let content;
    let extension;
    switch (this.config.exportFormat) {
      case "json":
        content = JSON.stringify(report, null, 2);
        extension = "json";
        break;
      case "markdown":
        content = this.generateMarkdownReport(report);
        extension = "md";
        break;
      case "html":
      default:
        content = this.generateHTMLReport(report);
        extension = "html";
        break;
    }
    const exportPath = path.join(".ralph-debug", `${filename}.${extension}`);
    await fs.mkdir(path.dirname(exportPath), { recursive: true });
    await fs.writeFile(exportPath, content);
    return exportPath;
  }
  // Helper methods
  determineIterationPhase(ralphDir) {
    return "working";
  }
  async calculateContextSize(ralphDir) {
    try {
      const feedbackPath = path.join(ralphDir, "feedback.txt");
      const feedback = await fs.readFile(feedbackPath, "utf8");
      return feedback.length;
    } catch {
      return 0;
    }
  }
  captureStackTrace() {
    const stack = new Error().stack || "";
    return stack.split("\n").slice(1, 6).join("\n");
  }
  findConsecutiveFailures(iterations) {
    const failures = [];
    let currentStreak = 0;
    for (const iteration of iterations) {
      if (!iteration.success) {
        currentStreak++;
      } else {
        if (currentStreak > 0) {
          failures.push(currentStreak);
        }
        currentStreak = 0;
      }
    }
    if (currentStreak > 0) {
      failures.push(currentStreak);
    }
    return failures;
  }
  calculateGrowthRate(sizes) {
    if (sizes.length < 2) return 0;
    const first = sizes[0];
    const last = sizes[sizes.length - 1];
    return first > 0 ? (last - first) / first : 0;
  }
  calculateMemoryEfficiency(memoryUsage) {
    if (memoryUsage.length < 2) return 1;
    const min = Math.min(...memoryUsage);
    const max = Math.max(...memoryUsage);
    return max > 0 ? min / max : 1;
  }
  generateTimelineHTML(timeline) {
    return `
<!DOCTYPE html>
<html>
<head>
    <title>${timeline.title}</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .timeline { margin: 20px 0; }
        .iteration { margin: 10px 0; padding: 10px; border-left: 4px solid #ccc; }
        .success { border-left-color: #4CAF50; }
        .failure { border-left-color: #F44336; }
    </style>
</head>
<body>
    <h1>${timeline.title}</h1>
    <div class="timeline">
        ${timeline.iterations.map((iter) => `
            <div class="iteration ${iter.success ? "success" : "failure"}">
                <h3>Iteration ${iter.iteration}</h3>
                <p>Duration: ${iter.duration}ms</p>
                <p>Changes: ${iter.changes} | Errors: ${iter.errors}</p>
                <p>Context Size: ${iter.contextSize}</p>
            </div>
        `).join("")}
    </div>
</body>
</html>
    `;
  }
  generateVisualizationHTML(session) {
    return `
<!DOCTYPE html>
<html>
<head>
    <title>Ralph Loop Visualization - ${session.loopId}</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .chart { margin: 20px 0; }
        .metric { display: inline-block; margin: 10px; padding: 10px; border: 1px solid #ccc; }
    </style>
</head>
<body>
    <h1>Ralph Loop Debug Visualization</h1>
    <div id="metrics">
        <div class="metric">
            <h3>Iterations</h3>
            <p>${session.iterations.length}</p>
        </div>
        <div class="metric">
            <h3>Avg Time</h3>
            <p>${Math.round(session.performance.averageIterationTime)}ms</p>
        </div>
        <div class="metric">
            <h3>Context Efficiency</h3>
            <p>${Math.round(session.performance.contextEfficiency * 100)}%</p>
        </div>
    </div>
    <div id="timeline" class="chart"></div>
    <script>
        // D3.js visualization code would go here
        console.log('Visualization data:', ${JSON.stringify(session)});
    </script>
</body>
</html>
    `;
  }
  generateMarkdownReport(report) {
    return `
# Ralph Loop Debug Report

**Loop ID:** ${report.loopId}
**Generated:** ${new Date(report.generatedAt).toLocaleString()}

## Summary
- **Total Iterations:** ${report.summary.totalIterations}
- **Success Rate:** ${Math.round(report.summary.successRate * 100)}%
- **Total Duration:** ${report.summary.totalDuration}ms
- **Average Iteration Time:** ${Math.round(report.summary.averageIterationTime)}ms

## Performance Analysis
- **Peak Memory:** ${Math.round(report.performanceAnalysis.resourceUtilization.memory / 1024 / 1024)}MB
- **Context Efficiency:** ${Math.round(report.performanceAnalysis.resourceUtilization.context * 100)}%

## Recommendations
${report.recommendations.map((r) => `- ${r}`).join("\n")}
    `;
  }
  generateHTMLReport(report) {
    return `
<!DOCTYPE html>
<html>
<head>
    <title>Ralph Debug Report - ${report.loopId}</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }
        .summary { background: #f5f5f5; padding: 20px; border-radius: 8px; margin: 20px 0; }
        .metric { display: inline-block; margin: 10px; padding: 15px; background: white; border-radius: 4px; }
        .recommendations { background: #e3f2fd; padding: 15px; border-radius: 4px; }
    </style>
</head>
<body>
    <h1>Ralph Loop Debug Report</h1>
    <div class="summary">
        <h2>Executive Summary</h2>
        <div class="metric">
            <h3>${report.summary.totalIterations}</h3>
            <p>Total Iterations</p>
        </div>
        <div class="metric">
            <h3>${Math.round(report.summary.successRate * 100)}%</h3>
            <p>Success Rate</p>
        </div>
        <div class="metric">
            <h3>${Math.round(report.summary.averageIterationTime)}ms</h3>
            <p>Avg Iteration Time</p>
        </div>
    </div>
    
    <div class="recommendations">
        <h2>Recommendations</h2>
        <ul>
            ${report.recommendations.map((r) => `<li>${r}</li>`).join("")}
        </ul>
    </div>
</body>
</html>
    `;
  }
  /**
   * Stop debug session and cleanup
   */
  async stopDebugSession(loopId) {
    const session = this.activeSessions.get(loopId);
    if (!session) return;
    if (session.monitoringInterval) {
      clearInterval(session.monitoringInterval);
    }
    await this.generateDebugReport(loopId);
    this.activeSessions.delete(loopId);
    logger.info("Debug session stopped", { loopId });
  }
}
const ralphDebugger = new RalphDebugger();
export {
  RalphDebugger,
  ralphDebugger
};
//# sourceMappingURL=ralph-debugger.js.map
