import { describe, test, expect } from 'bun:test';
import { Hono } from 'hono';
import { createHealthRoutes } from '../src/health.js';
import { createMetricsRoutes, metricsMiddleware, metrics } from '../src/metrics.js';
import { MemoryPrekeyStore } from '../src/memory-store.js';

describe('Health endpoints', () => {
  test('GET /health returns ok with version and uptime', async () => {
    const store = new MemoryPrekeyStore();
    const app = createHealthRoutes(store, '1.2.3');

    const res = await app.request('/health');
    expect(res.status).toBe(200);
    const body = await res.json();
    expect(body.status).toBe('ok');
    expect(body.version).toBe('1.2.3');
    expect(body.uptimeSeconds).toBeGreaterThanOrEqual(0);
  });

  test('GET /healthz returns text "ok"', async () => {
    const store = new MemoryPrekeyStore();
    const app = createHealthRoutes(store, '1.0.0');
    const res = await app.request('/healthz');
    expect(res.status).toBe(200);
    expect(await res.text()).toBe('ok');
  });

  test('GET /ready returns text "ready"', async () => {
    const store = new MemoryPrekeyStore();
    const app = createHealthRoutes(store, '1.0.0');
    const res = await app.request('/ready');
    expect(res.status).toBe(200);
    expect(await res.text()).toBe('ready');
  });

  test('returns 503 if store throws', async () => {
    const broken = {
      getOneTimePreKeyCount: async () => { throw new Error('db down'); },
    } as any;
    const app = createHealthRoutes(broken, '1.0.0');
    const res = await app.request('/health');
    expect(res.status).toBe(503);
    const body = await res.json();
    expect(body.status).toBe('error');
  });
});

describe('Metrics endpoint', () => {
  test('returns Prometheus exposition format', async () => {
    // Trigger some metrics
    const app = new Hono();
    app.use('*', metricsMiddleware());
    app.get('/test', (c) => c.text('hello'));
    app.route('/', createMetricsRoutes());

    await app.request('/test');
    await app.request('/test');

    const res = await app.request('/metrics');
    expect(res.status).toBe(200);
    expect(res.headers.get('content-type')).toMatch(/text\/plain/);
    const body = await res.text();
    expect(body).toContain('shade_requests_total');
    expect(body).toContain('shade_request_duration_ms');
  });
});
