import { describe, it, expect } from "vitest";
import { RecordingMetrics } from "@/instrumentation/recording-metrics";

describe("RecordingMetrics", () => {
  it("records counter calls with kind, name, value, and attributes", () => {
    const recording = new RecordingMetrics();
    recording.counter("http.requests", 1, { method: "GET", route: "/api/me" });

    expect(recording.metrics).toHaveLength(1);
    const [m] = recording.metrics;
    expect(m!.kind).toBe("counter");
    expect(m!.name).toBe("http.requests");
    expect(m!.value).toBe(1);
    expect(m!.attributes).toEqual({ method: "GET", route: "/api/me" });
  });

  it("counter() defaults value to 1 when omitted", () => {
    const recording = new RecordingMetrics();
    recording.counter("events.signups");

    expect(recording.metrics[0]!.value).toBe(1);
  });

  it("records histogram calls", () => {
    const recording = new RecordingMetrics();
    recording.histogram("http.duration", 123, { route: "/api/list" });

    expect(recording.metrics).toHaveLength(1);
    const [m] = recording.metrics;
    expect(m!.kind).toBe("histogram");
    expect(m!.name).toBe("http.duration");
    expect(m!.value).toBe(123);
    expect(m!.attributes).toEqual({ route: "/api/list" });
  });

  it("records gauge calls", () => {
    const recording = new RecordingMetrics();
    recording.gauge("queue.depth", 42, { queue: "emails" });

    expect(recording.metrics).toHaveLength(1);
    const [m] = recording.metrics;
    expect(m!.kind).toBe("gauge");
    expect(m!.name).toBe("queue.depth");
    expect(m!.value).toBe(42);
    expect(m!.attributes).toEqual({ queue: "emails" });
  });

  it("accumulates multiple calls across all kinds", () => {
    const recording = new RecordingMetrics();
    recording.counter("a");
    recording.histogram("b", 10);
    recording.gauge("c", 5);

    expect(recording.metrics).toHaveLength(3);
    expect(recording.metrics.map((m) => m.kind)).toEqual([
      "counter",
      "histogram",
      "gauge",
    ]);
  });

  it("reset() clears all recorded metrics", () => {
    const recording = new RecordingMetrics();
    recording.counter("x");
    recording.histogram("y", 1);
    expect(recording.metrics).toHaveLength(2);

    recording.reset();
    expect(recording.metrics).toHaveLength(0);
  });

  it("find() returns the first matching metric", () => {
    const recording = new RecordingMetrics();
    recording.counter("a");
    recording.histogram("b", 10);

    const found = recording.find((m) => m.kind === "histogram");
    expect(found).toBeDefined();
    expect(found!.name).toBe("b");
  });

  it("find() returns undefined when no metric matches", () => {
    const recording = new RecordingMetrics();
    recording.counter("a");

    const found = recording.find((m) => m.kind === "gauge");
    expect(found).toBeUndefined();
  });
});
