import fs from "fs";
import os from "os";
import path from "path";
import { afterEach, describe, expect, it } from "vitest";
import {
  findGraphDirsForService,
  findRuntimeStateDirs,
  normalizePathSeparators,
  readGraphMetadata,
  writeGraphMetadata,
} from "./state.mjs";

const tempDirs = [];

afterEach(() => {
  for (const dir of tempDirs.splice(0)) {
    fs.rmSync(dir, { recursive: true, force: true });
  }
});

function mkTempDir() {
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), "testkit-runner-state-"));
  tempDirs.push(dir);
  return dir;
}

describe("runner-state", () => {
  it("finds runtime state directories", () => {
    const rootDir = mkTempDir();
    const deep = path.join(rootDir, "workers", "w1", "deps", "api");
    fs.mkdirSync(deep, { recursive: true });
    fs.writeFileSync(path.join(rootDir, "workers", "database_backend"), "local");
    fs.writeFileSync(path.join(deep, "database_backend"), "local");

    const found = findRuntimeStateDirs(
      rootDir,
      (dir) => fs.existsSync(path.join(dir, "database_backend"))
    );

    expect(found).toEqual([
      deep,
      path.join(rootDir, "workers"),
    ]);
  });

  it("writes, reads, and finds graph metadata", () => {
    const productDir = mkTempDir();
    const graphDir = path.join(productDir, ".testkit", "_graphs", "api__frontend");
    writeGraphMetadata(graphDir, {
      runtimeNames: ["api", "frontend"],
      targetNames: ["frontend", "api"],
    });

    expect(readGraphMetadata(graphDir)).toEqual({
      runtimeServices: ["api", "frontend"],
      targetServices: ["api", "frontend"],
    });

    expect(findGraphDirsForService(productDir, "frontend")).toEqual([graphDir]);
    expect(normalizePathSeparators(`a${path.sep}b${path.sep}c`)).toBe("a/b/c");
  });
});
