import { describe, it, expect, beforeEach, afterEach } from "vitest";
import fs from "fs";
import os from "os";
import path from "path";
import { pruneRuntime, getDiskUsage, resetBuildkit } from "../src/modules/runtime.js";

let tmpDir: string;

function readMessages(tmpDir: string) {
  const messagesDir = path.join(tmpDir, "messages");
  if (!fs.existsSync(messagesDir)) return [];
  return fs.readdirSync(messagesDir)
    .filter((f) => f.endsWith(".json"))
    .map((f) => JSON.parse(fs.readFileSync(path.join(messagesDir, 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("pruneRuntime", () => {
  it("writes runtime-prune IPC message with scope", async () => {
    // Write result after short delay (after clearStaleResult runs)
    setTimeout(() => {
      fs.writeFileSync(path.join(tmpDir, "prune-result.json"), JSON.stringify({ timestamp: "2026-01-01", scope: "builder", output: "reclaimed 100MB" }));
    }, 100);
    await pruneRuntime("builder", tmpDir);
    const msgs = readMessages(tmpDir);
    expect(msgs).toHaveLength(1);
    expect(msgs[0]).toMatchObject({ type: "runtime-prune", scope: "builder", groupFolder: "test/group" });
  });

  it("accepts all valid scopes", async () => {
    // Run all scopes in parallel to avoid timeout
    const scopes = ["builder", "images", "images-all", "volumes", "all"] as const;
    await Promise.all(scopes.map(async (scope) => {
      const scopeDir = path.join(os.tmpdir(), "treehouse-test-" + Math.random().toString(36).slice(2));
      fs.mkdirSync(scopeDir, { recursive: true });
      setTimeout(() => {
        fs.writeFileSync(path.join(scopeDir, "prune-result.json"), JSON.stringify({ timestamp: "2026-01-01", scope, output: "" }));
      }, 100);
      await pruneRuntime(scope, scopeDir);
      const msgs = readMessages(scopeDir);
      expect(msgs[0]).toMatchObject({ type: "runtime-prune", scope });
      fs.rmSync(scopeDir, { recursive: true, force: true });
    }));
  });
});

describe("getDiskUsage", () => {
  it("writes runtime-disk-usage IPC message", async () => {
    setTimeout(() => {
      fs.writeFileSync(path.join(tmpDir, "disk-usage.json"), JSON.stringify({ timestamp: "2026-01-01", workspace_mb: 100 }));
    }, 100);
    await getDiskUsage(tmpDir);
    const msgs = readMessages(tmpDir);
    expect(msgs[0]).toMatchObject({ type: "runtime-disk-usage", groupFolder: "test/group" });
  });
});

describe("resetBuildkit", () => {
  it("writes buildkit-reset IPC message", async () => {
    setTimeout(() => {
      fs.writeFileSync(path.join(tmpDir, "buildkit-reset-result.json"), JSON.stringify({ timestamp: "2026-01-01", ok: true }));
    }, 100);
    await resetBuildkit(tmpDir);
    const msgs = readMessages(tmpDir);
    expect(msgs[0]).toMatchObject({ type: "buildkit-reset", groupFolder: "test/group" });
  });
});
