import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

vi.mock("@capakraken/api/sse", () => ({
  eventBus: { subscriberCount: 0 },
}));

// Lazy import so we can stub env before the module-level code runs.
const importRoute = () => import("./route.js");

describe("GET /api/perf — security hardening", () => {
  const ORIGINAL_SECRET = process.env["CRON_SECRET"];

  beforeEach(() => {
    vi.resetModules();
  });

  afterEach(() => {
    if (ORIGINAL_SECRET === undefined) {
      delete process.env["CRON_SECRET"];
    } else {
      process.env["CRON_SECRET"] = ORIGINAL_SECRET;
    }
  });

  it("returns 200 with metrics for an authorised request via Authorization header", async () => {
    process.env["CRON_SECRET"] = "test-secret-abc";
    const { GET } = await importRoute();

    const request = new Request("http://localhost/api/perf", {
      headers: { Authorization: "Bearer test-secret-abc" },
    });

    const response = await GET(request);
    expect(response.status).toBe(200);

    const body = await response.json() as { timestamp: string; uptime: unknown; memory: unknown };
    expect(typeof body.timestamp).toBe("string");
    expect(body.uptime).toBeDefined();
    expect(body.memory).toBeDefined();
  });

  it("returns 401 when no Authorization header is provided", async () => {
    process.env["CRON_SECRET"] = "test-secret-abc";
    const { GET } = await importRoute();

    const request = new Request("http://localhost/api/perf");
    const response = await GET(request);
    expect(response.status).toBe(401);
  });

  it("returns 401 when the Authorization header contains a wrong secret", async () => {
    process.env["CRON_SECRET"] = "test-secret-abc";
    const { GET } = await importRoute();

    const request = new Request("http://localhost/api/perf", {
      headers: { Authorization: "Bearer wrong-secret" },
    });
    const response = await GET(request);
    expect(response.status).toBe(401);
  });

  it("returns 401 for a query-param token — query-string auth is not supported", async () => {
    process.env["CRON_SECRET"] = "test-secret-abc";
    const { GET } = await importRoute();

    // Pass secret as query param only — no Authorization header
    const request = new Request("http://localhost/api/perf?token=test-secret-abc");
    const response = await GET(request);
    // The endpoint ignores query params entirely; without a valid header it must reject.
    expect(response.status).toBe(401);
  });

  it("returns 401 and leaks no metrics when CRON_SECRET is not configured (fail-closed)", async () => {
    delete process.env["CRON_SECRET"];
    const { GET } = await importRoute();

    // Even a request that would otherwise be valid must be rejected.
    const request = new Request("http://localhost/api/perf", {
      headers: { Authorization: "Bearer anything" },
    });
    const response = await GET(request);
    expect(response.status).toBe(401);

    const body = await response.json() as { error?: string; timestamp?: string; memory?: unknown };
    expect(body.timestamp).toBeUndefined();
    expect(body.memory).toBeUndefined();
  });
});
