import { describe, it, expect, beforeEach } from 'vitest';
import { Registry } from 'prom-client';
import { createWorkerMetrics } from './worker-metrics.js';

describe('metrics/worker-metrics', () => {
  let reg: Registry;

  beforeEach(() => {
    reg = new Registry();
  });

  it('registers all 6 metrics under the supplied prefix', async () => {
    createWorkerMetrics(reg, 'aao_worker_t');
    const out = await reg.metrics();
    for (const name of [
      'aao_worker_t_jobs_total',
      'aao_worker_t_active_jobs',
      'aao_worker_t_job_duration_seconds',
      'aao_worker_t_llm_calls_total',
      'aao_worker_t_llm_call_duration_seconds',
      'aao_worker_t_tool_calls_total',
    ]) {
      expect(out).toContain(name);
    }
  });

  it('activeJobs supports inc/dec', async () => {
    const m = createWorkerMetrics(reg, 'aao_worker_g');
    m.activeJobs.inc({ piece: 'chat', profile: 'main' });
    m.activeJobs.inc({ piece: 'chat', profile: 'main' });
    m.activeJobs.dec({ piece: 'chat', profile: 'main' });
    const out = await reg.metrics();
    expect(out).toMatch(/aao_worker_g_active_jobs\{piece="chat",profile="main"\} 1/);
  });

  it('tool calls split by success label', async () => {
    const m = createWorkerMetrics(reg, 'aao_worker_tc');
    m.toolCallsTotal.inc({ tool_name: 'Read', success: 'true' }, 5);
    m.toolCallsTotal.inc({ tool_name: 'Read', success: 'false' }, 1);
    const out = await reg.metrics();
    expect(out).toMatch(/aao_worker_tc_tool_calls_total\{tool_name="Read",success="true"\} 5/);
    expect(out).toMatch(/aao_worker_tc_tool_calls_total\{tool_name="Read",success="false"\} 1/);
  });

  it('LLM histogram observes seconds (not ms)', async () => {
    const m = createWorkerMetrics(reg, 'aao_worker_llm');
    m.llmCallDurationSeconds.observe(
      { worker_id: 'w1', backend_id: 'gpu-a', model: 'qwen3:8b' },
      2.5,
    );
    const out = await reg.metrics();
    expect(out).toMatch(/aao_worker_llm_llm_call_duration_seconds_sum\{[^}]+\} 2\.5/);
  });

  it('job-duration buckets fit minute-to-hour range', async () => {
    const m = createWorkerMetrics(reg, 'aao_worker_jd');
    m.jobDurationSeconds.observe(
      { piece: 'chat', status: 'succeeded', profile: 'main' },
      75,
    );
    const out = await reg.metrics();
    // The 120s bucket should be incremented (75 < 120)
    expect(out).toMatch(/aao_worker_jd_job_duration_seconds_bucket\{[^}]*le="120"[^}]*\} 1/);
    // The 60s bucket should NOT be incremented (75 > 60)
    expect(out).toMatch(/aao_worker_jd_job_duration_seconds_bucket\{[^}]*le="60"[^}]*\} 0/);
  });
});
