///|
pub struct RiskScore {
  score : Int
  level : String
  reasons : Array[String]
} derive(Eq, Debug)

///|
pub fn RiskScore::new(score : Int, reasons : Array[String]) -> RiskScore {
  let level = if score >= 80 {
    "critical"
  } else if score >= 50 {
    "high"
  } else if score >= 20 {
    "medium"
  } else {
    "low"
  }
  { score, level, reasons }
}

///|
fn risk_reason_count(result : VerificationResult) -> Int {
  let mut count = 0
  for i in 0.. RiskScore {
  let count = risk_reason_count(result)
  let mut score = 0
  for i in 0.. score = score + 60
      SignatureMismatch => score = score + 90
      MissingTimestamp => score = score + 35
      TimestampOutsideWindow => score = score + 70
      MissingEventId => score = score + 25
      ReplayDetected => score = score + 85
      DuplicateIdempotencyKey => score = score + 65
      UnknownEvent => score = score + 30
      ProviderMismatch => score = score + 55
      AcceptedDiagnostic => ()
    }
  }
  let mut offset = 0
  let reasons = Array::makei(count, _ => {
    while offset < result.diagnostics.length() &&
          result.diagnostics[offset].code == AcceptedDiagnostic {
      offset = offset + 1
    }
    let reason = diagnostic_name(result.diagnostics[offset].code)
    offset = offset + 1
    reason
  })
  RiskScore::new(score, reasons)
}

///|
pub fn batch_risk_scores(
  results : Array[VerificationResult],
) -> Array[RiskScore] {
  Array::makei(results.length(), i => score_result(results[i]))
}

///|
pub fn max_risk(scores : Array[RiskScore]) -> RiskScore {
  if scores.length() == 0 {
    RiskScore::new(0, [])
  } else {
    let mut best = scores[0]
    for i in 1.. best.score {
        best = scores[i]
      }
    }
    best
  }
}

///|
pub fn risk_table(scores : Array[RiskScore]) -> String {
  let builder = StringBuilder::new()
  builder.write_string("| score | level | reasons |\n")
  builder.write_string("| ---: | --- | --- |\n")
  for i in 0.. 0 {
        builder.write_string(";")
      }
      builder.write_string(scores[i].reasons[j])
    }
    builder.write_string(" |\n")
  }
  builder.to_string()
}

///|
pub fn explain_risk(score : RiskScore) -> String {
  let builder = StringBuilder::new()
  builder.write_string("level=")
  builder.write_string(score.level)
  builder.write_string(" score=")
  builder.write_string(score.score.to_string())
  if score.reasons.length() > 0 {
    builder.write_string(" reasons=")
    for i in 0.. 0 {
        builder.write_string(",")
      }
      builder.write_string(score.reasons[i])
    }
  }
  builder.to_string()
}