///|
/// Human-readable delivery diagnostic report.
pub(all) struct HookDiagnostic {
  provider : String
  event_type : String
  delivery_id : String
  route_name : String
  status : HookStatus
  verification : VerificationStatus
  retry_delay_ms : Int
  notes : Array[String]
} derive(Eq, Debug)

///|
/// Create a diagnostic report from common framework artifacts.
pub fn HookDiagnostic::HookDiagnostic(
  event : HookEvent,
  route_name : StringView,
  result : HookResult,
  verification : VerificationResult,
  retry_delay_ms? : Int = 0,
  notes? : ArrayView[String] = [],
) -> HookDiagnostic {
  {
    provider: event.provider.slug(),
    event_type: event.event_type,
    delivery_id: event.delivery_id,
    route_name: route_name.to_owned(),
    status: result.status,
    verification: verification.status,
    retry_delay_ms,
    notes: notes.to_owned(),
  }
}

///|
/// Render a compact one-line report.
pub fn HookDiagnostic::summary(self : HookDiagnostic) -> String {
  self.provider +
  "/" +
  self.event_type +
  " delivery=" +
  self.delivery_id +
  " route=" +
  self.route_name +
  " status=" +
  self.status.to_string() +
  " verification=" +
  self.verification.to_string()
}

///|
/// Render notes as a semicolon-separated suffix.
pub fn HookDiagnostic::notes_text(self : HookDiagnostic) -> String {
  let mut text = ""
  let mut first = true
  for note in self.notes {
    if first {
      text = note
      first = false
    } else {
      text = text + "; " + note
    }
  }
  text
}

///|
/// Build a report for a matched route.
pub fn report_matched_delivery(
  event : HookEvent,
  route : HookRoute,
  verification : VerificationResult,
) -> HookDiagnostic {
  HookDiagnostic(
    event,
    route.name,
    accepted(message="matched route " + route.name),
    verification,
  )
}

///|
/// Build a report for an unmatched delivery.
pub fn report_unmatched_delivery(
  event : HookEvent,
  verification : VerificationResult,
) -> HookDiagnostic {
  HookDiagnostic(
    event,
    "fallback",
    ignored(message="no route matched"),
    verification,
    notes=["register a route for " + event.event_type],
  )
}