import { expect, test } from "bun:test";
import { captureBrowserArtifacts, createFactory, withDatabaseRollback } from "../src/index.ts";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

test("factories are deterministic, bounded and override-safe", () => {
  const users = createFactory((sequence) => ({
    id: sequence,
    email: `user${sequence}@test.local`,
  }));
  expect(users.build().id).toBe(1);
  expect(users.build({ email: "custom@test.local" }).email).toBe("custom@test.local");
  users.reset();
  expect(users.buildMany(2).map((user) => user.id)).toEqual([1, 2]);
  expect(() => users.buildMany(10_001)).toThrow();
});

test("database isolation always rolls back while returning the test value", async () => {
  let rolledBack = false;
  const db = {
    async tx<T>(run: (transaction: any) => Promise<T>): Promise<T> {
      try {
        return await run(db);
      } catch (error) {
        rolledBack = true;
        throw error;
      }
    },
  };
  expect(await withDatabaseRollback(db, async () => 42)).toBe(42);
  expect(rolledBack).toBeTrue();
});

test("browser artifact helper writes safe screenshot and trace paths", async () => {
  const root = mkdtempSync(join(tmpdir(), "wrnexus-browser-artifacts-"));
  const calls: string[] = [];
  try {
    const result = await captureBrowserArtifacts(
      {
        async screenshot({ path }) {
          calls.push(path);
        },
        context() {
          return {
            tracing: {
              async stop({ path }) {
                calls.push(path);
              },
            },
          };
        },
      },
      "user / unsafe name",
      { root, trace: true },
    );
    expect(result.screenshot).toEndWith("user-unsafe-name.png");
    expect(result.trace).toEndWith("user-unsafe-name.zip");
    expect(calls).toHaveLength(2);
  } finally {
    rmSync(root, { recursive: true, force: true });
  }
});
