/**
 * Unit tests for src/routes/metrics.ts
 *
 * Verifies that GET /metrics returns 200 with Prometheus exposition format
 * and does NOT require authentication.
 */

import express, { Application } from 'express';
import request from 'supertest';
import { createMetricsRouter } from '../../../src/routes/metrics';
import { metricsRegistry } from '../../../src/metrics/registry';

// ────────────────────────────────────────────────────────────────────────────
// Helpers
// ────────────────────────────────────────────────────────────────────────────

/** Build a minimal Express app that mounts only the metrics router. */
function buildTestApp(): Application {
  const app = express();
  app.use('/metrics', createMetricsRouter());
  return app;
}

// ────────────────────────────────────────────────────────────────────────────
// Tests
// ────────────────────────────────────────────────────────────────────────────

describe('GET /metrics', () => {
  let app: Application;

  beforeEach(() => {
    metricsRegistry.resetMetrics();
    app = buildTestApp();
  });

  it('returns HTTP 200', async () => {
    const res = await request(app).get('/metrics');
    expect(res.status).toBe(200);
  });

  it('returns Content-Type containing text/plain', async () => {
    const res = await request(app).get('/metrics');
    expect(res.headers['content-type']).toMatch(/text\/plain/);
  });

  it('does NOT require an Authorization header', async () => {
    // Call without any auth header — must still succeed
    const res = await request(app).get('/metrics');
    expect(res.status).toBe(200);
    expect(res.status).not.toBe(401);
    expect(res.status).not.toBe(403);
  });

  it('response body contains agentidp_tokens_issued_total', async () => {
    const res = await request(app).get('/metrics');
    expect(res.text).toContain('agentidp_tokens_issued_total');
  });

  it('response body contains agentidp_agents_registered_total', async () => {
    const res = await request(app).get('/metrics');
    expect(res.text).toContain('agentidp_agents_registered_total');
  });

  it('response body contains agentidp_http_requests_total', async () => {
    const res = await request(app).get('/metrics');
    expect(res.text).toContain('agentidp_http_requests_total');
  });

  it('response body contains agentidp_http_request_duration_seconds', async () => {
    const res = await request(app).get('/metrics');
    expect(res.text).toContain('agentidp_http_request_duration_seconds');
  });

  it('response body contains agentidp_db_query_duration_seconds', async () => {
    const res = await request(app).get('/metrics');
    expect(res.text).toContain('agentidp_db_query_duration_seconds');
  });

  it('response body contains agentidp_redis_command_duration_seconds', async () => {
    const res = await request(app).get('/metrics');
    expect(res.text).toContain('agentidp_redis_command_duration_seconds');
  });

  it('response body is valid Prometheus text exposition format (starts with # HELP or TYPE)', async () => {
    const res = await request(app).get('/metrics');
    // Prometheus text format always begins with comment lines starting with '# '
    expect(res.text).toMatch(/^# (HELP|TYPE)/m);
  });
});
