import { createHash } from 'node:crypto';
import { Injectable } from '@nestjs/common';
import { assertLogUserIdSalt } from '../config/check-log-user-id-salt';

/**
 * Pseudonymises a user id (Entra `oid`) into the 16-hex-char hash
 * that both ADR-0013 (`audit_events.actor_id_hash`) and ADR-0012
 * (Pino `user_id_hash`) store. The salt is read once at injection
 * time so the per-request hot path runs purely on `node:crypto`.
 *
 * Same salt + same input ⇒ same output, on both writers, across
 * application restarts within a given environment. That stability
 * is the *whole point*: an investigator joins audit rows with app
 * log lines on this hash, then re-hydrates the join key to the
 * cleartext user id only inside the live operational DB.
 *
 * Rotating the salt invalidates the join key for everything that
 * was written before the rotation. Treat as long-lived per
 * environment.
 *
 * Hash construction:
 *   sha256(`${salt}:${userId}`).hex.slice(0, 16)
 *
 * SHA-256 is overkill for collision resistance at 16 hex chars
 * (64 bits of output), but truncation is intentional — log lines
 * and audit rows want a compact identifier, and 64 bits of
 * randomness is well above the birthday bound for any realistic
 * user count. The salt prevents rainbow attacks even on the
 * truncated form.
 */
@Injectable()
export class HashUserIdService {
  private readonly salt: string;

  constructor() {
    this.salt = assertLogUserIdSalt();
  }

  hash(userId: string): string {
    return createHash('sha256').update(`${this.salt}:${userId}`).digest('hex').slice(0, 16);
  }
}
