///|
pub(all) enum ErrorCategory {
  Authentication
  Freshness
  Identity
  Routing
  ProviderConfig
  Replay
  UnknownCategory
} derive(Eq, Debug)

///|
pub fn categorize(code : DiagnosticCode) -> ErrorCategory {
  match code {
    MissingSignature | SignatureMismatch => Authentication
    MissingTimestamp | TimestampOutsideWindow => Freshness
    MissingEventId | DuplicateIdempotencyKey => Identity
    UnknownEvent => Routing
    ProviderMismatch => ProviderConfig
    ReplayDetected => Replay
    AcceptedDiagnostic => UnknownCategory
  }
}

///|
pub fn category_name(category : ErrorCategory) -> String {
  match category {
    Authentication => "authentication"
    Freshness => "freshness"
    Identity => "identity"
    Routing => "routing"
    ProviderConfig => "provider_config"
    Replay => "replay"
    UnknownCategory => "unknown"
  }
}

///|
pub fn remediation(code : DiagnosticCode) -> String {
  match code {
    MissingSignature =>
      "Ensure the provider signature header is forwarded to the handler."
    SignatureMismatch =>
      "Check the shared secret and canonical payload construction."
    MissingTimestamp =>
      "Require a timestamp header from the provider or disable freshness only for trusted tests."
    TimestampOutsideWindow =>
      "Reject stale requests or increase tolerance for known clock skew."
    MissingEventId =>
      "Require provider delivery id or configure an idempotency fallback."
    ReplayDetected =>
      "Keep nonce storage active and reject duplicate signed deliveries."
    DuplicateIdempotencyKey => "Treat duplicate event ids as already processed."
    UnknownEvent => "Add a route rule or explicitly allow unhandled events."
    ProviderMismatch =>
      "Use the provider profile that matches the inbound request."
    AcceptedDiagnostic => "No action required."
  }
}

///|
pub fn diagnostic_to_help(diagnostic : GuardDiagnostic) -> String {
  diagnostic_name(diagnostic.code) +
  " [" +
  category_name(categorize(diagnostic.code)) +
  "]: " +
  remediation(diagnostic.code)
}

///|
pub fn result_help(result : VerificationResult) -> String {
  let builder = StringBuilder::new()
  for i in 0.. Bool {
  for i in 0..