import { BasePlugin } from "../../core/plugins/plugin-interface.js";
import { EventTypes } from "../../core/events/event-bus.js";
import { execSync } from "child_process";
import * as fs from "fs/promises";
import * as path from "path";
class SimpleRalphPlugin extends BasePlugin {
  name = "simple-ralph";
  version = "2.0.0";
  description = "Simplified Ralph loop for focused iterative development";
  activeTasks = /* @__PURE__ */ new Map();
  taskResults = /* @__PURE__ */ new Map();
  async onInitialize() {
    this.on(EventTypes.CONTEXT_LOADED, this.handleContextLoaded.bind(this));
  }
  async onStart() {
    console.log("Simple Ralph plugin started");
  }
  async onStop() {
    for (const taskId of this.activeTasks.keys()) {
      await this.cancelTask(taskId);
    }
  }
  async onShutdown() {
    this.activeTasks.clear();
    this.taskResults.clear();
  }
  onValidateConfig(config) {
    const errors = [];
    const warnings = [];
    if (config.options?.maxIterations && config.options.maxIterations > 100) {
      warnings.push("Max iterations > 100 may take a long time");
    }
    return { valid: true, errors, warnings };
  }
  /**
   * Run a simple iterative task
   */
  async runTask(task) {
    const taskId = task.id || this.generateTaskId();
    this.activeTasks.set(taskId, task);
    const result = {
      taskId,
      success: false,
      iterations: 0,
      totalDuration: 0,
      finalState: "initialized",
      results: []
    };
    const startTime = Date.now();
    const maxIterations = task.maxIterations || 10;
    try {
      this.emit(EventTypes.RALPH_ITERATION_START, {
        taskId,
        task: task.description,
        maxIterations
      });
      for (let i = 1; i <= maxIterations; i++) {
        const iterationResult = await this.runIteration(task, i);
        result.results.push(iterationResult);
        result.iterations = i;
        if (iterationResult.success) {
          result.success = true;
          result.finalState = "completed";
          break;
        }
        if (i < maxIterations && !this.shouldContinue(iterationResult)) {
          result.finalState = "stopped";
          break;
        }
      }
      result.totalDuration = Date.now() - startTime;
      this.emit(EventTypes.RALPH_LOOP_COMPLETE, {
        taskId,
        success: result.success,
        iterations: result.iterations,
        duration: result.totalDuration
      });
      this.taskResults.set(taskId, result);
      return result;
    } catch (error) {
      result.finalState = "failed";
      result.totalDuration = Date.now() - startTime;
      this.emit(EventTypes.RALPH_ITERATION_FAILED, {
        taskId,
        error: error instanceof Error ? error.message : String(error)
      });
      throw error;
    } finally {
      this.activeTasks.delete(taskId);
    }
  }
  /**
   * Run a single iteration
   */
  async runIteration(task, iteration) {
    const startTime = Date.now();
    const result = {
      iteration,
      success: false,
      changes: [],
      testsPassed: false,
      metrics: {
        duration: 0,
        filesChanged: 0,
        testsRun: 0
      }
    };
    try {
      const analysis = await this.analyzeCurrentState();
      const plan = await this.planChanges(task, analysis);
      const changes = await this.applyChanges(plan);
      result.changes = changes;
      result.metrics.filesChanged = changes.length;
      const testResult = await this.runTests();
      result.testsPassed = testResult.passed;
      result.metrics.testsRun = testResult.total;
      result.success = await this.checkAcceptanceCriteria(task, testResult);
      this.emit(EventTypes.RALPH_ITERATION_COMPLETE, {
        taskId: task.id,
        iteration,
        success: result.success,
        changes: changes.length
      });
    } catch (error) {
      result.errors = [error instanceof Error ? error.message : String(error)];
      this.emit(EventTypes.RALPH_ITERATION_FAILED, {
        taskId: task.id,
        iteration,
        error: result.errors[0]
      });
    }
    result.metrics.duration = Date.now() - startTime;
    return result;
  }
  /**
   * Analyze current project state
   */
  async analyzeCurrentState() {
    const analysis = {
      hasTests: false,
      hasPackageJson: false,
      gitStatus: "clean",
      lastCommit: ""
    };
    try {
      const packageJsonPath = path.join(process.cwd(), "package.json");
      try {
        await fs.access(packageJsonPath);
        analysis.hasPackageJson = true;
        const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
        analysis.hasTests = !!packageJson.scripts?.test;
      } catch {
      }
      try {
        analysis.gitStatus = execSync("git status --porcelain", { encoding: "utf-8" }).trim() || "clean";
        analysis.lastCommit = execSync("git log -1 --oneline", { encoding: "utf-8" }).trim();
      } catch {
      }
    } catch (error) {
      console.error("Error analyzing state:", error);
    }
    return analysis;
  }
  /**
   * Plan changes based on task and current state
   */
  async planChanges(task, analysis) {
    const changes = [];
    if (!analysis.hasTests && task.acceptanceCriteria.some((c) => c.includes("test"))) {
      changes.push("add-tests");
    }
    if (task.description.includes("refactor")) {
      changes.push("refactor-code");
    }
    if (task.description.includes("document")) {
      changes.push("add-documentation");
    }
    if (task.description.includes("optimize")) {
      changes.push("optimize-performance");
    }
    if (changes.length === 0) {
      changes.push("incremental-improvement");
    }
    return changes;
  }
  /**
   * Apply planned changes
   */
  async applyChanges(plan) {
    const appliedChanges = [];
    for (const change of plan) {
      try {
        switch (change) {
          case "add-tests":
            appliedChanges.push("Added test suite");
            break;
          case "refactor-code":
            appliedChanges.push("Refactored code structure");
            break;
          case "add-documentation":
            appliedChanges.push("Added documentation");
            break;
          case "optimize-performance":
            appliedChanges.push("Optimized performance");
            break;
          default:
            appliedChanges.push("Made incremental improvements");
        }
      } catch (error) {
        console.error(`Failed to apply change ${change}:`, error);
      }
    }
    return appliedChanges;
  }
  /**
   * Run project tests
   */
  async runTests() {
    try {
      const output = execSync("npm test", { encoding: "utf-8", stdio: "pipe" });
      const passed = !output.includes("failed") && !output.includes("error");
      const total = output.match(/\d+ (tests?|specs?)/i)?.[0]?.match(/\d+/)?.[0] || 0;
      return {
        passed,
        total: parseInt(String(total)) || 1,
        failed: passed ? 0 : 1
      };
    } catch (error) {
      return { passed: false, total: 0, failed: 1 };
    }
  }
  /**
   * Check if acceptance criteria are met
   */
  async checkAcceptanceCriteria(task, testResult) {
    for (const criterion of task.acceptanceCriteria) {
      const lower = criterion.toLowerCase();
      if (lower.includes("test") && !testResult.passed) {
        return false;
      }
      if (lower.includes("lint")) {
        try {
          execSync("npm run lint", { stdio: "pipe" });
        } catch {
          return false;
        }
      }
      if (lower.includes("build")) {
        try {
          execSync("npm run build", { stdio: "pipe" });
        } catch {
          return false;
        }
      }
    }
    return true;
  }
  /**
   * Determine if we should continue iterating
   */
  shouldContinue(result) {
    if (result.changes.length === 0) {
      return false;
    }
    if (result.errors && result.errors.length > 3) {
      return false;
    }
    return true;
  }
  /**
   * Cancel an active task
   */
  async cancelTask(taskId) {
    if (this.activeTasks.has(taskId)) {
      this.activeTasks.delete(taskId);
      this.emit("ralph.task.cancelled", { taskId });
    }
  }
  /**
   * Get task results
   */
  getTaskResult(taskId) {
    return this.taskResults.get(taskId);
  }
  /**
   * Get all active tasks
   */
  getActiveTasks() {
    return Array.from(this.activeTasks.values());
  }
  handleContextLoaded(event) {
    console.log("Context loaded, can use for enhanced planning");
  }
  generateTaskId() {
    return `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  }
}
function createSimpleRalphPlugin(config) {
  return new SimpleRalphPlugin();
}
export {
  SimpleRalphPlugin,
  createSimpleRalphPlugin
};
//# sourceMappingURL=simple-ralph-plugin.js.map
