/**
 * Anonymization module for request/response sanitization.
 *
 * Removes PII (Personally Identifiable Information) from outbound payloads
 * and ensures the synthetic marker CB26_MARKER_<uuid> is not leaked.
 *
 * Sanitization is applied to the WHOLE serialized JSON payload so PII
 * nested at any depth is redacted, not just top-level fields.
 */

// PII redaction patterns, applied to the serialized payload string.
const EMAIL_REGEX = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
const IPV4_REGEX = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
const IPV6_REGEX = /\b(?:[0-9a-fA-F]{1,4}:){2,7}[0-9a-fA-F]{1,4}\b/g;
const PHONE_REGEX = /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g;
const SSN_REGEX = /\b\d{3}-\d{2}-\d{4}\b/g;
const API_KEY_REGEX = /\b[A-Za-z0-9_\-]{32,}\b/g;
const CC_REGEX = /\b(?:\d[ -]*?){13,19}\b/g;
const MARKER_REGEX = /\bCB26_MARKER_[A-Za-z0-9_-]+\b/g;

/**
 * Sanitizes a request object by removing PII patterns from the whole payload.
 * Patterns redacted: email, IPv4/IPv6 address, phone number, SSN, API keys,
 * credit cards, and the synthetic CB26_MARKER_ marker.
 */
export function sanitizeRequest(req: unknown): unknown {
  if (req === null || req === undefined) {
    return req;
  }
  return JSON.parse(
    JSON.stringify(req)
      .replace(EMAIL_REGEX, "[REDACTED_EMAIL]")
      .replace(IPV4_REGEX, "[REDACTED_IP]")
      .replace(IPV6_REGEX, "[REDACTED_IP]")
      .replace(PHONE_REGEX, "[REDACTED_PHONE]")
      .replace(SSN_REGEX, "[REDACTED_SSN]")
      .replace(API_KEY_REGEX, "[REDACTED_API_KEY]")
      .replace(CC_REGEX, "[REDACTED_CC]")
      .replace(MARKER_REGEX, "[REDACTED_MARKER]"),
  );
}

/**
 * Sanitizes a response object by removing embedded synthetic markers
 * and any PII that may have been echoed back.
 */
export function sanitizeResponse(res: unknown): unknown {
  if (res === null || res === undefined) {
    return res;
  }
  return JSON.parse(
    JSON.stringify(res)
      .replace(MARKER_REGEX, "[REDACTED_MARKER]")
      .replace(EMAIL_REGEX, "[REDACTED_EMAIL]")
      .replace(IPV4_REGEX, "[REDACTED_IP]")
      .replace(IPV6_REGEX, "[REDACTED_IP]")
      .replace(PHONE_REGEX, "[REDACTED_PHONE]")
      .replace(SSN_REGEX, "[REDACTED_SSN]")
      .replace(API_KEY_REGEX, "[REDACTED_API_KEY]")
      .replace(CC_REGEX, "[REDACTED_CC]"),
  );
}
