import fs from "fs";
import os from "os";
import path from "path";
import { pathToFileURL } from "url";
import { afterEach, describe, expect, it } from "vitest";
import {
  ensurePlaywrightTestConfig,
  findPlaywrightConfig,
  resolvePlaywrightOutputDir,
} from "./playwright-config.mjs";

const cleanups = [];

afterEach(() => {
  while (cleanups.length > 0) {
    cleanups.pop()();
  }
});

function makeTempDir(prefix) {
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
  cleanups.push(() => fs.rmSync(dir, { recursive: true, force: true }));
  return dir;
}

describe("runner-playwright-config", () => {
  it("uses a lease-local output directory under the lease dir", async () => {
    const productDir = makeTempDir("testkit-playwright-product-");
    const leaseDir = path.join(productDir, ".testkit", "leases", "lease-12");
    const cwd = path.join(productDir, "frontend");
    fs.mkdirSync(cwd, { recursive: true });
    fs.writeFileSync(
      path.join(cwd, "playwright.config.mjs"),
      "export default { outputDir: 'shared-test-results', workers: 8, fullyParallel: true, webServer: { command: 'npm run dev', url: 'http://127.0.0.1:3000' } };\n"
    );

    const configPath = ensurePlaywrightTestConfig(
      { name: "frontend", productDir, stateDir: path.join(productDir, ".testkit", "frontend") },
      cwd,
      ["frontend/__testkit__/homepage/homepage.pw.testkit.ts"],
      { leaseDir }
    );
    const generated = await import(pathToFileURL(configPath).href + `?t=${Date.now()}`);

    const expectedOutputDir = resolvePlaywrightOutputDir(leaseDir);
    expect(generated.default.outputDir).toBe(expectedOutputDir);
    expect(generated.default.workers).toBe(1);
    expect(generated.default.fullyParallel).toBe(false);
    expect(generated.default.webServer).toBeUndefined();
    expect(fs.existsSync(expectedOutputDir)).toBe(true);
    expect(fs.readFileSync(configPath, "utf8")).toContain(
      `outputDir: ${JSON.stringify(expectedOutputDir)}`
    );
    expect(fs.readFileSync(configPath, "utf8")).toContain("workers: 1");
    expect(fs.readFileSync(configPath, "utf8")).toContain("fullyParallel: false");
  });

  it("requires a lease-scoped directory", () => {
    const productDir = makeTempDir("testkit-playwright-product-");
    const cwd = path.join(productDir, "frontend");
    fs.mkdirSync(cwd, { recursive: true });

    expect(() =>
      ensurePlaywrightTestConfig(
        { name: "frontend", productDir, stateDir: path.join(productDir, ".testkit", "frontend") },
        cwd,
        ["frontend/__testkit__/homepage/homepage.pw.testkit.ts"]
      )
    ).toThrow('Playwright task for service "frontend" requires a lease-scoped directory');
  });

  it("finds a supported playwright config file", () => {
    const cwd = makeTempDir("testkit-playwright-cwd-");
    fs.writeFileSync(path.join(cwd, "playwright.config.ts"), "export default {};\n");

    expect(findPlaywrightConfig(cwd)).toBe(path.join(cwd, "playwright.config.ts"));
  });
});
