///|
pub struct DbcAudit {
  database_value : DbcDatabase
  validation_value : DbcValidationResult
  statistics_value : DbcStatistics
  canonical_text_value : String
  round_trip_consistent_value : Bool
} derive(Eq, Debug)

///|
pub fn DbcAudit::database(self : DbcAudit) -> DbcDatabase {
  self.database_value
}

///|
pub fn DbcAudit::validation(self : DbcAudit) -> DbcValidationResult {
  self.validation_value
}

///|
pub fn DbcAudit::statistics(self : DbcAudit) -> DbcStatistics {
  self.statistics_value
}

///|
pub fn DbcAudit::canonical_text(self : DbcAudit) -> String {
  self.canonical_text_value
}

///|
pub fn DbcAudit::round_trip_consistent(self : DbcAudit) -> Bool {
  self.round_trip_consistent_value
}

///|
pub fn DbcAudit::accepted(self : DbcAudit) -> Bool {
  self.validation_value.is_valid() && self.round_trip_consistent_value
}

///|
pub fn audit_dbc(
  text : String,
  limits? : DbcParseLimits = DbcParseLimits::standard(),
  policy? : DbcValidationPolicy = DbcValidationPolicy::strict_classic_can(),
) -> Result[DbcAudit, DbcError] {
  let database = match parse_dbc(text, limits~) {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let validation = validate_dbc(database, policy~)
  let statistics = analyze_dbc(database)
  let canonical = match serialize_dbc(database) {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let reparsed = match parse_dbc(canonical, limits~) {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  Ok({
    database_value: database,
    validation_value: validation,
    statistics_value: statistics,
    canonical_text_value: canonical,
    round_trip_consistent_value: database_content_equal(database, reparsed),
  })
}

///|
pub fn render_audit_text(audit : DbcAudit) -> String {
  let mut output = "DBC audit: accepted=\{audit.accepted()}, round_trip_consistent=\{audit.round_trip_consistent()}\n"
  output = output + render_statistics_text(audit.statistics())
  output + render_validation_text(audit.validation())
}

///|
pub fn render_audit_json(audit : DbcAudit) -> String {
  "{\"accepted\":\{audit.accepted()},\"round_trip_consistent\":\{audit.round_trip_consistent()},\"statistics\":" +
  render_statistics_json(audit.statistics()) +
  ",\"validation\":" +
  render_validation_json(audit.validation()) +
  "}"
}