import fs from "fs";
import path from "path";
import { pathToFileURL } from "url";
import { normalizePathSeparators } from "./state.mjs";

export function ensurePlaywrightTestConfig(targetConfig, cwd, requestedFiles, lease) {
  if (!lease?.leaseDir) {
    throw new Error(
      `Playwright task for service "${targetConfig.name}" requires a lease-scoped directory`
    );
  }

  const stateDir = lease.leaseDir;
  const outputDir = resolvePlaywrightOutputDir(stateDir);
  fs.mkdirSync(stateDir, { recursive: true });
  fs.mkdirSync(outputDir, { recursive: true });
  const configPath = path.join(stateDir, "playwright.testkit.config.mjs");
  const baseConfigPath = findPlaywrightConfig(cwd);
  const normalizedFiles = requestedFiles.map(normalizePathSeparators);

  let source = "";
  if (baseConfigPath) {
    source =
      `import baseConfig from ${JSON.stringify(pathToFileURL(baseConfigPath).href)};\n` +
      `const resolvedBase = typeof baseConfig === "function" ? await baseConfig() : baseConfig;\n` +
      `export default {\n` +
      `  ...(resolvedBase || {}),\n` +
      `  testDir: ${JSON.stringify(cwd)},\n` +
      `  testMatch: ${JSON.stringify(normalizedFiles)},\n` +
      `  outputDir: ${JSON.stringify(outputDir)},\n` +
      `  workers: 1,\n` +
      `  fullyParallel: false,\n` +
      `  webServer: undefined,\n` +
      `};\n`;
  } else {
    source =
      `export default {\n` +
      `  testDir: ${JSON.stringify(cwd)},\n` +
      `  testMatch: ${JSON.stringify(normalizedFiles)},\n` +
      `  outputDir: ${JSON.stringify(outputDir)},\n` +
      `  workers: 1,\n` +
      `  fullyParallel: false,\n` +
      `};\n`;
  }

  fs.writeFileSync(configPath, source);
  return configPath;
}

export function resolvePlaywrightOutputDir(stateDir) {
  return path.join(stateDir, "playwright-output");
}

export function findPlaywrightConfig(cwd) {
  const candidates = [
    "playwright.config.ts",
    "playwright.config.mts",
    "playwright.config.js",
    "playwright.config.mjs",
    "playwright.config.cjs",
    "playwright.config.cts",
  ];

  for (const candidate of candidates) {
    const candidatePath = path.join(cwd, candidate);
    if (fs.existsSync(candidatePath)) {
      return candidatePath;
    }
  }

  return null;
}
