///|
fn strategy_text(strategy : Strategy) -> String {
  match strategy {
    SinglePoint => "single"
    RepeatedPoint(count~) => "repeat:" + count.to_string()
    Scan(count~) => "scan:" + count.to_string()
  }
}

///|
fn verdict_text(verdict : Verdict) -> String {
  match verdict {
    Pass => "pass"
    Fail(_) => "fail"
    Unmeasured => "unmeasured"
  }
}

///|
fn severity_text(severity : DiagnosticSeverity) -> String {
  match severity {
    Info => "INFO"
    Warning => "WARN"
    Error => "ERROR"
  }
}

///|
/// Render stable one-line entries for an audit trace.
pub fn render_trace_entries(entries : Array[AuditEntry]) -> String {
  let mut output = ""
  for entry in entries {
    output = output +
      "feature=" +
      entry.feature_id +
      " device=" +
      entry.device_id +
      " strategy=" +
      strategy_text(entry.strategy) +
      " uncertainty=" +
      entry.uncertainty.to_string() +
      " verdict=" +
      verdict_text(entry.verdict) +
      "\n"
  }
  output
}

///|
/// Render stable diagnostics with row indices.
pub fn render_diagnostics(diagnostics : Array[Diagnostic]) -> String {
  let mut output = ""
  for diagnostic in diagnostics {
    output = output +
      severity_text(diagnostic.severity) +
      "[" +
      diagnostic.index.to_string() +
      "] " +
      diagnostic.code +
      ": " +
      diagnostic.message +
      "\n"
  }
  output
}