import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { logger } from "../core/monitoring/logger.js";
import * as fs from "fs";
import * as path from "path";
const PROMPT_PLAN_PATH = "docs/specs/PROMPT_PLAN.md";
class LinearTaskRunner {
  constructor(taskManager, rlmOrchestrator, context, specSkill) {
    this.taskManager = taskManager;
    this.rlmOrchestrator = rlmOrchestrator;
    this.context = context;
    this.specSkill = specSkill;
  }
  /** Pull next task from Linear, execute via RLM, update status */
  async runNext(opts) {
    const tasks = this.getFilteredTasks(opts);
    if (tasks.length === 0) {
      return {
        success: true,
        message: "No pending tasks found",
        data: { tasksAvailable: 0 }
      };
    }
    const task = tasks[0];
    return this.runTask(task.id, opts);
  }
  /** Run all active tasks iteratively */
  async runAll(opts) {
    const startTime = Date.now();
    const tasks = this.getFilteredTasks(opts);
    if (tasks.length === 0) {
      return {
        success: true,
        message: "No pending tasks to execute",
        data: { tasksAvailable: 0 }
      };
    }
    if (opts?.dryRun) {
      return this.preview();
    }
    const summary = {
      completed: [],
      failed: [],
      skipped: [],
      totalTokens: 0,
      totalCost: 0,
      duration: 0
    };
    for (const task of tasks) {
      try {
        const result = await this.executeTask(task);
        if (result.success) {
          summary.completed.push(task.id);
          const data = result.data;
          summary.totalTokens += data?.totalTokens || 0;
          summary.totalCost += data?.totalCost || 0;
          await this.autoUpdatePromptPlan(task);
        } else {
          summary.failed.push({
            taskId: task.id,
            error: result.message
          });
        }
        await this.syncSafe();
      } catch (error) {
        const msg = error instanceof Error ? error.message : String(error);
        summary.failed.push({ taskId: task.id, error: msg });
        logger.error("Task execution failed", { taskId: task.id, error: msg });
      }
    }
    summary.duration = Date.now() - startTime;
    return {
      success: summary.failed.length === 0,
      message: `Completed ${summary.completed.length}/${tasks.length} tasks`,
      data: summary,
      action: `Executed ${summary.completed.length} tasks, ${summary.failed.length} failures`
    };
  }
  /** Execute a specific Linear task by ID */
  async runTask(taskId, opts) {
    const task = this.taskManager.getTask(taskId);
    if (!task) {
      return { success: false, message: `Task not found: ${taskId}` };
    }
    if (opts?.dryRun) {
      return this.previewTask(task);
    }
    const result = await this.executeTask(task);
    if (result.success) {
      await this.autoUpdatePromptPlan(task);
      await this.syncSafe();
    }
    return result;
  }
  /** Show execution plan without running */
  async preview(taskId) {
    if (taskId) {
      const task = this.taskManager.getTask(taskId);
      if (!task) {
        return { success: false, message: `Task not found: ${taskId}` };
      }
      return this.previewTask(task);
    }
    const tasks = this.getFilteredTasks();
    const plan = tasks.map((t, i) => ({
      order: i + 1,
      id: t.id,
      identifier: t.externalIdentifier || t.id,
      title: t.title,
      priority: t.priority || "medium",
      status: t.status,
      tags: t.tags
    }));
    return {
      success: true,
      message: `${plan.length} tasks in execution queue`,
      data: { plan, totalTasks: plan.length }
    };
  }
  // --- Private helpers ---
  async executeTask(task) {
    const taskLabel = task.externalIdentifier || task.id;
    logger.info("Starting task execution", {
      taskId: task.id,
      title: task.title
    });
    try {
      this.taskManager.updateTaskStatus(
        task.id,
        "in_progress",
        "LinearTaskRunner: starting execution"
      );
    } catch {
    }
    try {
      const result = await this.rlmOrchestrator.execute(
        task.description || task.title,
        {
          linearTaskId: task.id,
          linearIdentifier: task.externalIdentifier,
          title: task.title,
          tags: task.tags
        }
      );
      if (result.success) {
        this.taskManager.updateTaskStatus(
          task.id,
          "done",
          `Completed via RLM: ${result.improvements.length} improvements, ${result.testsGenerated} tests`
        );
        return {
          success: true,
          message: `${taskLabel}: completed`,
          data: {
            taskId: task.id,
            duration: result.duration,
            totalTokens: result.totalTokens,
            totalCost: result.totalCost,
            testsGenerated: result.testsGenerated,
            improvements: result.improvements.length,
            issuesFound: result.issuesFound,
            issuesFixed: result.issuesFixed
          },
          action: `Executed ${taskLabel} via RLM`
        };
      } else {
        logger.warn("Task execution failed", {
          taskId: task.id,
          rootNode: result.rootNode
        });
        return {
          success: false,
          message: `${taskLabel}: execution failed`,
          data: {
            taskId: task.id,
            duration: result.duration,
            totalTokens: result.totalTokens
          }
        };
      }
    } catch (error) {
      const msg = error instanceof Error ? error.message : String(error);
      logger.error("Task execution threw", { taskId: task.id, error: msg });
      return {
        success: false,
        message: `${taskLabel}: ${msg}`,
        data: { taskId: task.id }
      };
    }
  }
  getFilteredTasks(opts) {
    const tasks = this.taskManager.getTasksByStatus("todo");
    let filtered = tasks;
    if (opts?.priority) {
      filtered = filtered.filter((t) => t.priority === opts.priority);
    }
    if (opts?.tag) {
      const tag = opts.tag;
      filtered = filtered.filter((t) => t.tags.includes(tag));
    }
    const priorityOrder = {
      urgent: 0,
      high: 1,
      medium: 2,
      low: 3
    };
    return filtered.sort(
      (a, b) => (priorityOrder[a.priority || "medium"] || 2) - (priorityOrder[b.priority || "medium"] || 2)
    );
  }
  previewTask(task) {
    return {
      success: true,
      message: `Preview: ${task.externalIdentifier || task.id}`,
      data: {
        id: task.id,
        identifier: task.externalIdentifier,
        title: task.title,
        description: task.description?.slice(0, 200),
        priority: task.priority,
        status: task.status,
        tags: task.tags,
        willExecuteVia: "RLM Orchestrator",
        estimatedSteps: [
          "Planning agent decomposes task",
          "Code/Test/Review subagents execute",
          "Multi-stage review",
          "Update Linear status to done"
        ]
      }
    };
  }
  /** Auto-update PROMPT_PLAN checkboxes when a task completes */
  async autoUpdatePromptPlan(task) {
    if (!this.specSkill) return;
    const promptPlanPath = path.join(process.cwd(), PROMPT_PLAN_PATH);
    if (!fs.existsSync(promptPlanPath)) return;
    try {
      await this.specSkill.update(PROMPT_PLAN_PATH, task.title);
      logger.info("Auto-updated PROMPT_PLAN checkbox", {
        taskId: task.id,
        title: task.title
      });
    } catch {
    }
  }
  /** Safe Linear sync — log errors but don't throw */
  async syncSafe() {
    try {
      await this.taskManager.syncWithLinear();
    } catch (error) {
      const msg = error instanceof Error ? error.message : String(error);
      logger.warn("Linear sync failed (non-fatal)", { error: msg });
    }
  }
}
export {
  LinearTaskRunner
};
//# sourceMappingURL=linear-task-runner.js.map
