import { describe, test, expect } from "bun:test";
import { createHealthRoutes } from "@/server/routes/health.js";

interface HealthBody {
  status: string;
  uptime: number;
}

interface MetricsBody {
  uptime: number;
  timestamp: string;
  memoryUsage: {
    rss: number;
    heapTotal: number;
    heapUsed: number;
  };
}

describe("createHealthRoutes", () => {
  test("GET /health returns 200 with status ok and numeric uptime", async () => {
    const app = createHealthRoutes();
    const res = await app.request("/health");
    expect(res.status).toBe(200);
    const body = (await res.json()) as HealthBody;
    expect(body.status).toBe("ok");
    expect(typeof body.uptime).toBe("number");
    expect(body.uptime).toBeGreaterThanOrEqual(0);
  });

  test("GET /metrics returns 200 with uptime, timestamp, and memoryUsage", async () => {
    const app = createHealthRoutes();
    const res = await app.request("/metrics");
    expect(res.status).toBe(200);
    const body = (await res.json()) as MetricsBody;
    expect(typeof body.uptime).toBe("number");
    expect(body.uptime).toBeGreaterThanOrEqual(0);
    expect(typeof body.timestamp).toBe("string");
    expect(body.memoryUsage).toBeDefined();
    expect(typeof body.memoryUsage.rss).toBe("number");
    expect(typeof body.memoryUsage.heapTotal).toBe("number");
    expect(typeof body.memoryUsage.heapUsed).toBe("number");
  });

  test("GET /nonexistent returns 404", async () => {
    const app = createHealthRoutes();
    const res = await app.request("/nonexistent");
    expect(res.status).toBe(404);
  });

  test("returns 503 while not ready, 200 once ready", async () => {
    let ready = false;
    const app = createHealthRoutes(() => ready);

    const notReady = await app.request("/health");
    expect(notReady.status).toBe(503);

    ready = true;
    const nowReady = await app.request("/health");
    expect(nowReady.status).toBe(200);
    expect(await nowReady.json()).toMatchObject({ status: "ok" });
  });

  test("defaults to ready (200) when no isReady provided", async () => {
    const app = createHealthRoutes();
    const res = await app.request("/health");
    expect(res.status).toBe(200);
  });
});
