import fs from "fs";
import os from "os";
import path from "path";
import { afterEach, describe, expect, it } from "vitest";
import { discoverTests } from "./index.mjs";
import { buildHistoryTestId, saveHistory } from "../history/index.mjs";

const cleanups = [];

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

describe("public discovery", () => {
  it("returns resolved suites/files with human labels and persisted history", async () => {
    const productDir = createProduct();
    writeFile(
      productDir,
      "testkit.setup.ts",
      `
        import { defineTestkitSetup } from "@elench/testkit/setup";

        export default defineTestkitSetup({
          services: {
            api: {
              local: {
                cwd: ".",
                start: "node server.js",
                baseUrl: "http://127.0.0.1:3000",
                readyUrl: "http://127.0.0.1:3000"
              },
              requirements: {
                files: [
                  {
                    path: "src/api/routes/__testkit__/agent-configs-auth-gate.int.testkit.ts",
                    locks: ["route-lock"]
                  }
                ]
              }
            },
            frontend: {
              local: {
                cwd: "frontend",
                start: "node server.js",
                baseUrl: "http://127.0.0.1:3001",
                readyUrl: "http://127.0.0.1:3001"
              },
              dependsOn: ["api"],
              skip: {
                files: [
                  {
                    path: "frontend/src/app/login/__testkit__/auth.pw.testkit.ts",
                    reason: "Auth is stubbed locally"
                  }
                ]
              }
            }
          }
        });
      `
    );
    writeFile(productDir, "src/api/routes/__testkit__/agent-configs-auth-gate.int.testkit.ts");
    writeFile(productDir, "frontend/src/app/login/__testkit__/auth.pw.testkit.ts");

    saveHistory(productDir, {
      version: 1,
      tests: {
        [buildHistoryTestId("api", "int", "src/api/routes/__testkit__/agent-configs-auth-gate.int.testkit.ts")]: {
          id: buildHistoryTestId("api", "int", "src/api/routes/__testkit__/agent-configs-auth-gate.int.testkit.ts"),
          path: "src/api/routes/__testkit__/agent-configs-auth-gate.int.testkit.ts",
          service: "api",
          suiteName: "routes",
          selectionType: "int",
          framework: "k6",
          firstSeenAt: "2026-04-01T00:00:00.000Z",
          lastSeenAt: "2026-04-02T00:00:00.000Z",
          lastRunAt: "2026-04-02T00:00:00.000Z",
          runCount: 4,
          passCount: 3,
          failCount: 1,
          skipCount: 0,
          notRunCount: 0,
          avgDurationMs: 2500,
          durationCount: 4,
          lastStatus: "passed",
        },
      },
    });

    const result = await discoverTests({ dir: productDir });
    expect(result.summary).toMatchObject({
      services: 2,
      suites: 2,
      files: 2,
      activeFiles: 1,
      skippedFiles: 1,
      byType: {
        int: 1,
        pw: 1,
      },
    });
    expect(result.history.available).toBe(true);
    expect(result.services.map((entry) => entry.name)).toEqual(["api", "frontend"]);

    const apiFile = result.files.find((entry) => entry.service === "api");
    expect(apiFile).toMatchObject({
      displayName: "Agent Configs Auth Gate",
      suiteName: "routes",
      groupLabel: "Routes",
      selectionType: "int",
      skipped: false,
      locks: ["route-lock"],
    });
    expect(apiFile.history).toMatchObject({
      firstSeenAt: "2026-04-01T00:00:00.000Z",
      runCount: 4,
      passCount: 3,
      failCount: 1,
      avgDurationMs: 2500,
    });

    const frontendFile = result.files.find((entry) => entry.service === "frontend");
    expect(frontendFile).toMatchObject({
      displayName: "Auth",
      selectionType: "pw",
      skipped: true,
      skipReason: "Auth is stubbed locally",
      dependsOn: ["api"],
    });
  });

  it("reports legacy discovery diagnostics without failing in report mode", async () => {
    const productDir = createProduct();
    writeFile(
      productDir,
      "testkit.setup.ts",
      `
        import { defineTestkitSetup } from "@elench/testkit/setup";

        export default defineTestkitSetup({
          services: {
            api: {
              local: {
                cwd: ".",
                start: "node server.js",
                baseUrl: "http://127.0.0.1:3000",
                readyUrl: "http://127.0.0.1:3000"
              }
            }
          }
        });
      `
    );
    writeFile(productDir, "src/api/routes/__testkit__/health/health.int.testkit.ts");
    writeFile(productDir, "tests/api/integration/legacy.int.testkit.ts");

    const result = await discoverTests({ dir: productDir, diagnostics: "report" });
    expect(result.files).toHaveLength(1);
    expect(result.diagnostics).toEqual(
      expect.arrayContaining([
        expect.objectContaining({
          code: "legacy_path",
          path: "tests/api/integration/legacy.int.testkit.ts",
        }),
      ])
    );
  });
});

function createProduct() {
  const productDir = fs.mkdtempSync(path.join(os.tmpdir(), "testkit-discovery-public-"));
  cleanups.push(() => fs.rmSync(productDir, { recursive: true, force: true }));
  return productDir;
}

function writeFile(productDir, relativePath, contents = "export {};\n") {
  const absolutePath = path.join(productDir, relativePath);
  fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
  fs.writeFileSync(absolutePath, contents);
}
