///|
pub(all) struct BatchOutcome {
  analyses : Array[AnalysisOutcome]
  files : Int
  errors : Int
  warnings : Int
}

///|
pub fn analyze_batch(
  files : Array[@source.SourceFile],
  config : @lint.LintConfig,
) -> BatchOutcome {
  let analyses : Array[AnalysisOutcome] = []
  let mut errors = 0
  let mut warnings = 0
  for file in files {
    let analysis = analyze_source(file, config)
    let report = analysis.report()
    errors += report.errors
    warnings += report.warnings
    analyses.push(analysis)
  }
  { analyses, files: files.length(), errors, warnings }
}

///|
pub fn BatchOutcome::has_errors(self : BatchOutcome) -> Bool {
  self.errors > 0
}

///|
pub fn BatchOutcome::total_diagnostics(self : BatchOutcome) -> Int {
  let mut total = 0
  for analysis in self.analyses {
    total += analysis.report().total()
  }
  total
}

///|
pub fn BatchOutcome::summary(self : BatchOutcome) -> String {
  "files=" +
  self.files.to_string() +
  ", errors=" +
  self.errors.to_string() +
  ", warnings=" +
  self.warnings.to_string() +
  ", diagnostics=" +
  self.total_diagnostics().to_string()
}

///|
pub fn BatchOutcome::all_diagnostics(
  self : BatchOutcome,
) -> Array[@diagnostic.Diagnostic] {
  let result : Array[@diagnostic.Diagnostic] = []
  for analysis in self.analyses {
    for diagnostic in analysis.diagnostics {
      result.push(diagnostic)
    }
  }
  result
}

///|
pub fn BatchOutcome::render(self : BatchOutcome, format : CliFormat) -> String {
  match format {
    Text => @diagnostic.render_diagnostic_table(self.all_diagnostics())
    Json => {
      let builder = StringBuilder()
      builder.write_string("{\"summary\":\"")
      builder.write_string(self.summary())
      builder.write_string("\",\"diagnostics\":")
      builder.write_string(
        @diagnostic.render_json(self.all_diagnostics()).trim_end().to_owned(),
      )
      builder.write_string("}\n")
      builder.to_string()
    }
    Sarif =>
      if self.analyses.length() == 0 {
        "{\"version\":\"2.1.0\",\"runs\":[]}\n"
      } else {
        @diagnostic.render_sarif(
          self.all_diagnostics(),
          self.analyses[0].source,
        )
      }
  }
}