import { describe, expect, it } from "vitest";
import { clusterReasons, reasonClusterKey } from "./reasons";

describe("reasonClusterKey", () => {
  it("takes the text before the first colon", () => {
    expect(reasonClusterKey("manifest stale: thisUpdate in the past")).toBe("manifest stale");
    expect(
      reasonClusterKey("manifest is not valid at validation_time: this_update=2023-01-01"),
    ).toBe("manifest is not valid at validation_time");
  });
  it("keeps reasons without a colon intact", () => {
    expect(reasonClusterKey("certificate expired")).toBe("certificate expired");
  });
  it("trims whitespace around the prefix", () => {
    expect(reasonClusterKey("bad roa : detail")).toBe("bad roa");
  });
});

describe("clusterReasons", () => {
  it("merges reasons sharing a prefix and sums counts", () => {
    const clusters = clusterReasons({
      "manifest stale: thisUpdate in the past": 3,
      "manifest stale: nextUpdate missing": 2,
      "certificate expired: notAfter 2026-01-01": 5,
    });
    expect(clusters).toEqual([
      { key: "certificate expired", count: 5, variants: 1 },
      { key: "manifest stale", count: 5, variants: 2 },
    ]);
  });
  it("sorts by count desc, then key asc for determinism", () => {
    const clusters = clusterReasons({ "b: 1": 4, "a: 2": 4, "c": 1 });
    expect(clusters.map((c) => c.key)).toEqual(["a", "b", "c"]);
  });
  it("honours the limit", () => {
    const clusters = clusterReasons({ "a: 1": 3, "b: 2": 2, "c: 3": 1 }, 2);
    expect(clusters.map((c) => c.key)).toEqual(["a", "b"]);
  });
});
