///|
pub enum ArchiveError {
  NonIncreasingRevision
  EmptyNote
} derive(Debug, Eq)

///|
pub struct ReportSnapshot {
  revision : Int
  report : ChemReport
  note : String
} derive(Debug, Eq)

///|
pub struct ReportArchive {
  id : String
  snapshots : Array[ReportSnapshot]
} derive(Debug, Eq)

///|
pub fn snapshot(
  revision : Int,
  report : ChemReport,
  note : String,
) -> ReportSnapshot {
  { revision, report, note }
}

///|
pub fn report_archive(id : String) -> ReportArchive {
  { id, snapshots: [] }
}

///|
pub fn ReportArchive::append(
  self : ReportArchive,
  value : ReportSnapshot,
) -> Result[ReportArchive, ArchiveError] {
  if value.note.trim() == "" {
    return Err(EmptyNote)
  }
  if self.snapshots.length() > 0 &&
    value.revision <= self.snapshots[self.snapshots.length() - 1].revision {
    return Err(NonIncreasingRevision)
  }
  self.snapshots.push(value)
  Ok(self)
}

///|
pub fn ReportArchive::latest(self : ReportArchive) -> ReportSnapshot? {
  if self.snapshots.length() == 0 {
    None
  } else {
    Some(self.snapshots[self.snapshots.length() - 1])
  }
}

///|
pub fn ReportArchive::history(self : ReportArchive) -> Array[ReportSnapshot] {
  self.snapshots.copy()
}