/**
 * E2E test fixture generator for the Electrobun prototype.
 *
 * Creates isolated temp directories with demo groups.json, settings.db,
 * and a scratch git repo. Cleanup happens automatically on test end.
 */

import { mkdirSync, writeFileSync, rmSync } from "node:fs";
import { execSync } from "node:child_process";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { randomUUID } from "node:crypto";

export interface TestFixture {
  /** Root temp directory for this test run. */
  rootDir: string;
  /** ~/.config/agor equivalent for test isolation. */
  configDir: string;
  /** ~/.local/share/agor equivalent for test isolation. */
  dataDir: string;
  /** A scratch git repo with an initial commit. */
  repoDir: string;
  /** Environment variables to pass to the app process. */
  env: Record<string, string>;
  /** Remove all fixture files (best-effort). */
  cleanup: () => void;
}

/** Default groups matching the app's seed data. */
const DEMO_GROUPS = [
  { id: "dev", name: "Development", icon: "\uD83D\uDD27", position: 0 },
  { id: "test", name: "Testing", icon: "\uD83E\uddEA", position: 1 },
  { id: "ops", name: "DevOps", icon: "\uD83D\uDE80", position: 2 },
  { id: "research", name: "Research", icon: "\uD83D\uDD2C", position: 3 },
];

/** Demo project config for test assertions. */
const DEMO_PROJECTS = [
  {
    id: "test-project-1",
    name: "test-project",
    cwd: "", // filled in with repoDir
    accent: "var(--ctp-mauve)",
    provider: "claude",
    groupId: "dev",
  },
];

/**
 * Create an isolated test fixture with config/data dirs, groups.json,
 * and a git repo with one commit.
 */
export function createTestFixture(prefix = "agor-ebun-e2e"): TestFixture {
  const rootDir = join(tmpdir(), `${prefix}-${randomUUID().slice(0, 8)}`);
  const configDir = join(rootDir, "config", "agor");
  const dataDir = join(rootDir, "data", "agor");
  const repoDir = join(rootDir, "repo");

  // Create directory tree
  mkdirSync(configDir, { recursive: true });
  mkdirSync(dataDir, { recursive: true });
  mkdirSync(repoDir, { recursive: true });

  // Write demo groups.json
  writeFileSync(
    join(configDir, "groups.json"),
    JSON.stringify({ groups: DEMO_GROUPS }, null, 2),
  );

  // Update demo project CWD to point at the scratch repo
  const projects = DEMO_PROJECTS.map((p) => ({ ...p, cwd: repoDir }));
  writeFileSync(
    join(configDir, "projects.json"),
    JSON.stringify(projects, null, 2),
  );

  // Initialise a scratch git repo with one commit
  execSync("git init && git commit --allow-empty -m 'init'", {
    cwd: repoDir,
    stdio: "ignore",
    env: {
      ...process.env,
      GIT_AUTHOR_NAME: "test",
      GIT_AUTHOR_EMAIL: "test@test",
      GIT_COMMITTER_NAME: "test",
      GIT_COMMITTER_EMAIL: "test@test",
    },
  });

  const env: Record<string, string> = {
    AGOR_TEST: "1",
    AGOR_TEST_CONFIG_DIR: configDir,
    AGOR_TEST_DATA_DIR: dataDir,
  };

  function cleanup() {
    try {
      rmSync(rootDir, { recursive: true, force: true });
    } catch {
      /* best-effort */
    }
  }

  return { rootDir, configDir, dataDir, repoDir, env, cleanup };
}
