///|
fn csv_field(value : String) -> String {
  "\"\{value.replace_all(old="\"", new="\"\"")}\""
}

///|
pub fn render_csv_report(report : BenchmarkReport) -> String {
  let rows : Array[String] = [
    "kind,query_id,metric,mean,min,max,relevant,retrieved",
  ]
  for metric in report.summary {
    rows.push(
      "\{csv_field("summary")},\{csv_field("")},\{csv_field(metric.name)},\{metric.mean},\{metric.min},\{metric.max},,",
    )
  }
  for query in report.queries {
    for cutoff in report.cutoffs {
      let recall = query.metrics.get_or_default(
        metric_name("recall", cutoff),
        0.0,
      )
      let ndcg = query.metrics.get_or_default(metric_name("ndcg", cutoff), 0.0)
      rows.push(
        "\{csv_field("query")},\{csv_field(query.query_id)},\{csv_field("recall@\{cutoff};ndcg@\{cutoff}")},\{recall},\{ndcg},,\{query.relevant_total},\{query.retrieved_total}",
      )
    }
  }
  rows.join("\n")
}

///|
pub fn render_json_lines_report(report : BenchmarkReport) -> String {
  let rows : Array[String] = []
  for metric in report.summary {
    rows.push(
      "{\"kind\":\"summary\",\"metric\":\{ToJson::to_json(metric).stringify()}",
    )
  }
  for query in report.queries {
    rows.push(
      "{\"kind\":\"query\",\"query\":\{ToJson::to_json(query).stringify()}",
    )
  }
  rows.join("\n")
}

///|
pub fn render_validation_report(summary : ValidationSummary) -> String {
  let builder = StringBuilder()
  builder.write_string("# Dataset validation\n\n")
  builder.write_string("- Valid: \{summary.is_valid()}\n")
  builder.write_string("- Errors: \{summary.error_count}\n")
  builder.write_string("- Warnings: \{summary.warning_count}\n")
  builder.write_string("- Queries: \{summary.query_count}\n")
  builder.write_string("- Judged rows: \{summary.judged_count}\n")
  builder.write_string("- Retrieved rows: \{summary.retrieved_count}\n\n")
  if !summary.issues.is_empty() {
    builder.write_string("| Level | Code | Query | Document | Message |\n")
    builder.write_string("| --- | --- | --- | --- | --- |\n")
    for issue in summary.issues {
      let level = match issue.level {
        Error => "error"
        Warning => "warning"
      }
      builder.write_string(
        "| \{level} | \{issue.code} | \{issue.query_id} | \{issue.doc_id} | \{issue.message} |\n",
      )
    }
  }
  builder.to_string()
}