///|
/// A stable report model suitable for a CLI or service adapter.
pub(all) struct MonitoringReport {
  transaction_summary : TransactionSummary
  alert_count : Int
  high_risk_count : Int
  cases : Int
  invalid_records : Int
}

///|
pub fn build_report(
  rules : Array[Rule],
  transactions : Array[Transaction],
) -> MonitoringReport {
  let alerts = evaluate(rules, transactions)
  let cases = group_cases(alerts)
  let scores = aggregate_scores(alerts)
  let mut high = 0
  for score in scores {
    if score.total >= 70 {
      high += 1
    }
  }
  {
    transaction_summary: summarize(transactions),
    alert_count: alerts.length(),
    high_risk_count: high,
    cases: cases.length(),
    invalid_records: validate_batch(transactions).length(),
  }
}

///|
pub fn report_is_consistent(report : MonitoringReport) -> Bool {
  report.alert_count >= 0 &&
  report.high_risk_count >= 0 &&
  report.cases >= 0 &&
  report.invalid_records >= 0 &&
  report.high_risk_count <= report.alert_count
}

///|
pub fn risk_band_name(severity : AlertSeverity) -> String {
  match severity {
    Info => "info"
    Low => "low"
    Medium => "medium"
    High => "high"
    Critical => "critical"
  }
}

///|
pub fn status_name(status : AlertStatus) -> String {
  match status {
    Open => "open"
    Triaged => "triaged"
    Escalated => "escalated"
    Resolved => "resolved"
    Dismissed => "dismissed"
  }
}

///|
pub fn summarize_alerts(alerts : Array[Alert]) -> Array[String] {
  let result : Array[String] = []
  for alert in alerts {
    result.push(
      "rule=\{alert.rule_id};transaction=\{alert.transaction_id};status=\{status_name(alert.status)}",
    )
  }
  result
}