import { describe, it, expect, beforeEach, afterEach } from "vitest";
import fs from "fs";
import os from "os";
import path from "path";
import { scheduleTask, pauseTask, resumeTask, cancelTask, updateTask } from "../src/modules/tasks.js";

let tmpDir: string;

function readTaskIpc(tmpDir: string) {
  const tasksDir = path.join(tmpDir, "tasks");
  if (!fs.existsSync(tasksDir)) return [];
  return fs.readdirSync(tasksDir)
    .filter((f) => f.endsWith(".json"))
    .map((f) => JSON.parse(fs.readFileSync(path.join(tasksDir, f), "utf8")));
}

beforeEach(() => {
  tmpDir = path.join(os.tmpdir(), "treehouse-test-" + Math.random().toString(36).slice(2));
  fs.mkdirSync(tmpDir, { recursive: true });
  process.env.TENANT_ID = "test-tenant";
  process.env.NANOCLAW_GROUP_FOLDER = "test/group";
});

afterEach(() => {
  fs.rmSync(tmpDir, { recursive: true, force: true });
  delete process.env.TENANT_ID;
  delete process.env.NANOCLAW_GROUP_FOLDER;
});

describe("scheduleTask", () => {
  it("writes schedule_task IPC file", async () => {
    await scheduleTask(
      { prompt: "Do something", scheduleType: "cron", scheduleValue: "0 9 * * *" },
      tmpDir
    );
    const items = readTaskIpc(tmpDir);
    expect(items).toHaveLength(1);
    expect(items[0]).toMatchObject({
      type: "schedule_task",
      prompt: "Do something",
      scheduleType: "cron",
      scheduleValue: "0 9 * * *",
      groupFolder: "test/group",
    });
  });

  it("includes contextMode when provided", async () => {
    await scheduleTask(
      { prompt: "Do something", scheduleType: "once", scheduleValue: "2026-01-01T09:00:00", contextMode: "isolated" },
      tmpDir
    );
    const items = readTaskIpc(tmpDir);
    expect(items[0]).toMatchObject({ contextMode: "isolated" });
  });
});

describe("pauseTask", () => {
  it("writes pause_task IPC file", async () => {
    await pauseTask("task-123", tmpDir);
    const items = readTaskIpc(tmpDir);
    expect(items[0]).toMatchObject({ type: "pause_task", id: "task-123", groupFolder: "test/group" });
  });
});

describe("resumeTask", () => {
  it("writes resume_task IPC file", async () => {
    await resumeTask("task-456", tmpDir);
    const items = readTaskIpc(tmpDir);
    expect(items[0]).toMatchObject({ type: "resume_task", id: "task-456", groupFolder: "test/group" });
  });
});

describe("cancelTask", () => {
  it("writes cancel_task IPC file", async () => {
    await cancelTask("task-789", tmpDir);
    const items = readTaskIpc(tmpDir);
    expect(items[0]).toMatchObject({ type: "cancel_task", id: "task-789", groupFolder: "test/group" });
  });
});

describe("updateTask", () => {
  it("writes update_task IPC file with params", async () => {
    await updateTask("task-abc", { prompt: "New prompt", scheduleType: "interval", scheduleValue: "3600000" }, tmpDir);
    const items = readTaskIpc(tmpDir);
    expect(items[0]).toMatchObject({
      type: "update_task",
      id: "task-abc",
      prompt: "New prompt",
      scheduleType: "interval",
      scheduleValue: "3600000",
      groupFolder: "test/group",
    });
  });

  it("writes update_task with partial params", async () => {
    await updateTask("task-abc", { prompt: "Updated prompt only" }, tmpDir);
    const items = readTaskIpc(tmpDir);
    expect(items[0]).toMatchObject({ type: "update_task", id: "task-abc", prompt: "Updated prompt only" });
  });
});
