///|
pub struct SourceAudit {
  total : Int
  with_url : Int
  missing_citation : Int
  duplicate_citations : Int
} derive(Debug, Eq)

///|
pub fn audit_sources(report : ChemReport) -> SourceAudit {
  let with_url = report.sources.fold(init=0, (count, item) => {
    if item.url.trim() == "" {
      count
    } else {
      count + 1
    }
  })
  let missing_citation = report.sources.fold(init=0, (count, item) => {
    if item.citation.trim() == "" {
      count + 1
    } else {
      count
    }
  })
  let citations = [ for item in report.sources => item.citation ]
  let duplicate_citations = repeated(citations).length()
  {
    total: report.sources.length(),
    with_url,
    missing_citation,
    duplicate_citations,
  }
}

///|
pub fn SourceAudit::is_traceable(self : SourceAudit) -> Bool {
  self.total > 0 && self.missing_citation == 0 && self.duplicate_citations == 0
}