import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { RequestMetrics } from '../../src/resources/requestMetrics.js';

describe('RequestMetrics', () => {
  describe('initial state', () => {
    it('starts with zero api call count', () => {
      const metrics = RequestMetrics.startRequest();
      const result = metrics.endRequest();
      assert.equal(result.apiCallCount, 0);
    });

    it('starts with zero total api duration', () => {
      const metrics = RequestMetrics.startRequest();
      const result = metrics.endRequest();
      assert.equal(result.totalApiDurationNs, 0);
    });

    it('starts with zero total throttle delay', () => {
      const metrics = RequestMetrics.startRequest();
      const result = metrics.endRequest();
      assert.equal(result.totalThrottleDelayNs, 0);
    });
  });

  describe('endRequest', () => {
    it('returns elapsed duration since construction', () => {
      const before = process.hrtime.bigint();
      const metrics = RequestMetrics.startRequest();
      const result = metrics.endRequest();
      const after = process.hrtime.bigint();
      assert.ok(result.durationNs >= 0n);
      assert.ok(result.durationNs <= after - before);
    });
  });

  describe('recordExternalApiCall', () => {
    it('increments api call count', () => {
      const metrics = RequestMetrics.startRequest();
      metrics.recordExternalApiCall(100, 0);
      metrics.recordExternalApiCall(200, 0);
      const result = metrics.endRequest();
      assert.equal(result.apiCallCount, 2);
    });

    it('accumulates api duration', () => {
      const metrics = RequestMetrics.startRequest();
      const firstCallDuration = 100;
      const secondCallDuration = 250;
      metrics.recordExternalApiCall(firstCallDuration, 0);
      metrics.recordExternalApiCall(secondCallDuration, 0);
      const result = metrics.endRequest();
      assert.equal(result.totalApiDurationNs, firstCallDuration + secondCallDuration);
    });

    it('accumulates throttle delay', () => {
      const metrics = RequestMetrics.startRequest();
      const firstThrottleDelay = 30;
      const secondThrottleDelay = 70;
      metrics.recordExternalApiCall(100, firstThrottleDelay);
      metrics.recordExternalApiCall(200, secondThrottleDelay);
      const result = metrics.endRequest();
      assert.equal(result.totalThrottleDelayNs, firstThrottleDelay + secondThrottleDelay);
    });

    it('accumulates api duration and throttle delay independently', () => {
      const metrics = RequestMetrics.startRequest();
      const duration = 100;
      const throttleDelay = 40;
      metrics.recordExternalApiCall(duration, throttleDelay);
      const result = metrics.endRequest();
      assert.equal(result.totalApiDurationNs, duration);
      assert.equal(result.totalThrottleDelayNs, throttleDelay);
    });
  });
});
