import { afterEach, beforeEach, describe, expect, test } from "bun:test";
import dgram from "node:dgram";
import { DatadogMetrics } from "@/metrics/datadog-recorder.js";
import { mockLogger } from "../_helpers/mock-logger.js";

/**
 * Verifies the real hot-shots-backed adapter actually emits well-formed DogStatsD
 * UDP packets (prefix + global tags + per-call tags) for every method — the "metric
 * lands on the wire" criterion, not merely "does not throw".
 */
describe("DatadogMetrics (real UDP emission)", () => {
  const PORT = 18225;
  let server: dgram.Socket;
  let packets: string[];

  beforeEach(async () => {
    packets = [];
    server = dgram.createSocket("udp4");
    server.on("message", (msg) => packets.push(msg.toString()));
    await new Promise<void>((resolve) => server.bind(PORT, "127.0.0.1", resolve));
  });

  afterEach(() => {
    server.close();
  });

  async function flush(): Promise<void> {
    await new Promise((r) => setTimeout(r, 200));
  }

  test("emits prefixed, tagged packets for every metric type", async () => {
    const m = new DatadogMetrics("127.0.0.1", PORT, "dev", "cursor", mockLogger());

    m.increment("poll.executed", { poller: "jira" });
    m.count("poll.enqueued", 3, { poller: "jira" });
    m.gauge("queue.depth", 4, { poller: "jira" });
    m.histogram("jobs.duration", 1200, { job_kind: "jira" });
    m.timing("poll.duration", 50, { poller: "jira" });
    await flush();

    const joined = packets.join("\n");
    expect(joined).toContain("hu_agent.poll.executed:1|c|");
    expect(joined).toContain("hu_agent.poll.enqueued:3|c|");
    expect(joined).toContain("hu_agent.queue.depth:4|g|");
    expect(joined).toContain("hu_agent.jobs.duration:1200|h|");
    expect(joined).toContain("hu_agent.poll.duration:50|ms|");
    // global tags + per-call tag both present
    expect(joined).toContain("service:hu-agent");
    expect(joined).toContain("env:dev");
    expect(joined).toContain("poller:jira");
  });

  test("emits without tags when none are passed", async () => {
    const m = new DatadogMetrics("127.0.0.1", PORT, "dev", "cursor", mockLogger());
    m.increment("queue.high_load");
    await flush();
    expect(packets.join("\n")).toContain("hu_agent.queue.high_load:1|c|");
  });
});
