///|
pub(all) enum DiagnosticSeverity {
  Error
  Warning
} derive(Debug, Eq)

///|
pub(all) struct Diagnostic {
  severity : DiagnosticSeverity
  code : String
  line : Int
  column : Int
  field : String
  message : String
} derive(Debug, Eq)

///|
pub(all) struct ValidationOptions {
  strict : Bool
} derive(Debug, Eq)

///|
pub(all) struct ValidationReport {
  issues : Array[Diagnostic]
} derive(Debug, Eq)

///|
fn validation_severity(options : ValidationOptions) -> DiagnosticSeverity {
  if options.strict {
    DiagnosticSeverity::Error
  } else {
    DiagnosticSeverity::Warning
  }
}

///|
fn append_issue(
  issues : Array[Diagnostic],
  options~ : ValidationOptions,
  code~ : String,
  line~ : Int,
  column~ : Int,
  field~ : String,
  message~ : String,
) -> Unit {
  issues.push({
    severity: validation_severity(options),
    code,
    line,
    column,
    field,
    message,
  })
}

///|
fn has_name(names : Array[String], wanted : String) -> Bool {
  for name in names {
    if name == wanted {
      return true
    }
  }
  false
}

///|
fn definition_names(header : VcfHeader, kind : String) -> Array[String] {
  let names : Array[String] = []
  for item in header.meta {
    match item {
      MetaLine::Info(def) if kind == "INFO" => names.push(def.id)
      MetaLine::Format(def) if kind == "FORMAT" => names.push(def.id)
      MetaLine::Filter(def) if kind == "FILTER" => names.push(def.id)
      MetaLine::Contig(def) if kind == "CONTIG" => names.push(def.id)
      _ => ()
    }
  }
  names
}