import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { pseudonymize } from "./pseudonymize";

describe("pseudonymize", () => {
  const originalSalt = process.env["AUDIT_PSEUDONYM_SALT"];

  beforeEach(() => {
    process.env["AUDIT_PSEUDONYM_SALT"] = "test-salt-1";
  });

  afterEach(() => {
    if (originalSalt === undefined) {
      delete process.env["AUDIT_PSEUDONYM_SALT"];
    } else {
      process.env["AUDIT_PSEUDONYM_SALT"] = originalSalt;
    }
  });

  it("returns a string prefixed with 'erased-'", () => {
    const result = pseudonymize("user_42");
    expect(result).toMatch(/^erased-/);
  });

  it("produces exactly 16 hex chars after the prefix", () => {
    const result = pseudonymize("user_42");
    const hex = result.slice("erased-".length);
    expect(hex).toHaveLength(16);
    expect(hex).toMatch(/^[0-9a-f]+$/);
  });

  it("is deterministic — same salt + actorId always yields the same token", () => {
    const a = pseudonymize("user_42");
    const b = pseudonymize("user_42");
    expect(a).toBe(b);
  });

  it("differs when actorId differs (same salt)", () => {
    const a = pseudonymize("user_42");
    const b = pseudonymize("user_99");
    expect(a).not.toBe(b);
  });

  it("differs when the salt changes", () => {
    const withSalt1 = pseudonymize("user_42");

    process.env["AUDIT_PSEUDONYM_SALT"] = "test-salt-2";
    const withSalt2 = pseudonymize("user_42");

    expect(withSalt1).not.toBe(withSalt2);
  });

  it("uses the fallback salt when env var is absent", () => {
    delete process.env["AUDIT_PSEUDONYM_SALT"];
    // Should not throw; just use the fallback.
    const result = pseudonymize("user_1");
    expect(result).toMatch(/^erased-[0-9a-f]{16}$/);
  });
});
