///|
fn evidence_ref(
  code : String,
  category : String,
  source : String,
  description : String,
  typical_scope : String,
) -> EvidenceReference {
  { code, category, source, description, typical_scope }
}

///|
pub fn evidence_references() -> Array[EvidenceReference] {
  [
    evidence_ref(
      "experimental", "experiment", "generic", "Feature is supported by direct experimental observation",
      "curated genes and regulatory features",
    ),
    evidence_ref(
      "expression", "experiment", "generic", "Feature is supported by transcript expression evidence",
      "transcripts and exons",
    ),
    evidence_ref(
      "rna_seq", "experiment", "generic", "Feature is supported by RNA sequencing reads",
      "transcripts and splice junctions",
    ),
    evidence_ref(
      "est", "experiment", "generic", "Feature is supported by expressed sequence tag alignment",
      "transcripts and exons",
    ),
    evidence_ref(
      "cdna", "experiment", "generic", "Feature is supported by cDNA alignment",
      "transcripts and exons",
    ),
    evidence_ref(
      "proteomics", "experiment", "generic", "Feature is supported by peptide or protein evidence",
      "CDS and polypeptide features",
    ),
    evidence_ref(
      "mass_spectrometry", "experiment", "generic", "Feature is supported by mass spectrometry evidence",
      "protein coding products",
    ),
    evidence_ref(
      "chip_seq", "experiment", "generic", "Feature is supported by ChIP-seq signal",
      "regulatory regions",
    ),
    evidence_ref(
      "dnase_seq", "experiment", "generic", "Feature is supported by DNase accessibility signal",
      "open chromatin regions",
    ),
    evidence_ref(
      "atac_seq", "experiment", "generic", "Feature is supported by ATAC-seq accessibility signal",
      "open chromatin regions",
    ),
    evidence_ref(
      "cage", "experiment", "generic", "Feature is supported by capped transcript evidence",
      "transcription start sites",
    ),
    evidence_ref(
      "polyA_seq", "experiment", "generic", "Feature is supported by polyadenylation evidence",
      "polyA sites",
    ),
    evidence_ref(
      "homology", "inference", "generic", "Feature is inferred from similarity to another sequence",
      "genes and proteins",
    ),
    evidence_ref(
      "protein_homology", "inference", "generic", "Feature is inferred from protein sequence similarity",
      "CDS and polypeptides",
    ),
    evidence_ref(
      "transcript_homology", "inference", "generic", "Feature is inferred from transcript sequence similarity",
      "transcripts",
    ),
    evidence_ref(
      "ab_initio_prediction", "inference", "generic", "Feature is predicted from sequence model alone",
      "candidate genes",
    ),
    evidence_ref(
      "gene_prediction", "inference", "generic", "Feature is produced by a gene prediction program",
      "gene models",
    ),
    evidence_ref(
      "repeat_prediction", "inference", "generic", "Feature is inferred by repeat detection software",
      "repeat regions",
    ),
    evidence_ref(
      "profile_hmm", "inference", "generic", "Feature is inferred by a profile hidden Markov model",
      "protein domains",
    ),
    evidence_ref(
      "curated", "curation", "generic", "Feature has been reviewed by a curator",
      "high confidence annotation",
    ),
    evidence_ref(
      "manual_annotation", "curation", "generic", "Feature coordinates or attributes were manually edited",
      "genes and transcripts",
    ),
    evidence_ref(
      "community_annotation", "curation", "generic", "Feature is contributed by community annotation",
      "organism community datasets",
    ),
    evidence_ref(
      "imported", "provenance", "generic", "Feature was imported from another annotation release",
      "migration reports",
    ),
    evidence_ref(
      "liftover", "provenance", "generic", "Feature was transferred between assemblies",
      "assembly migration",
    ),
    evidence_ref(
      "projection", "provenance", "generic", "Feature was projected from a related genome",
      "comparative annotation",
    ),
    evidence_ref(
      "merged", "provenance", "generic", "Feature was produced by merging multiple sources",
      "integrated annotations",
    ),
    evidence_ref(
      "refseq_curated", "curation", "RefSeq", "Feature follows RefSeq curated annotation practice",
      "RefSeq gene sets",
    ),
    evidence_ref(
      "refseq_predicted", "inference", "RefSeq", "Feature is predicted in a RefSeq annotation pipeline",
      "RefSeq predicted models",
    ),
    evidence_ref(
      "best_refseq", "curation", "NCBI", "Feature is marked as a preferred RefSeq-supported model",
      "NCBI GFF3",
    ),
    evidence_ref(
      "gnomon", "inference", "NCBI", "Feature is produced by the NCBI Gnomon pipeline",
      "NCBI gene prediction",
    ),
    evidence_ref(
      "ensembl_havana", "curation", "Ensembl", "Feature is reconciled between Ensembl and HAVANA annotation",
      "GENCODE and Ensembl GTF",
    ),
    evidence_ref(
      "havana_manual", "curation", "HAVANA", "Feature has manual HAVANA curation support",
      "GENCODE transcripts",
    ),
    evidence_ref(
      "appris_principal", "selection", "APPRIS", "Transcript is selected as a principal isoform",
      "protein coding transcripts",
    ),
    evidence_ref(
      "appris_alternative", "selection", "APPRIS", "Transcript is selected as an alternative isoform",
      "protein coding transcripts",
    ),
    evidence_ref(
      "ccds", "cross_reference", "CCDS", "Coding sequence is linked to a CCDS identifier",
      "coding transcripts",
    ),
    evidence_ref(
      "mane_select", "selection", "MANE", "Transcript is selected by the MANE project",
      "human clinical annotation",
    ),
    evidence_ref(
      "mane_plus_clinical", "selection", "MANE", "Transcript is included for clinical relevance",
      "human clinical annotation",
    ),
    evidence_ref(
      "tsl1", "support_level", "GENCODE", "Transcript support level indicates all splice junctions are well supported",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "tsl2", "support_level", "GENCODE", "Transcript support level indicates one splice junction has weaker support",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "tsl3", "support_level", "GENCODE", "Transcript support level indicates moderate support",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "tsl4", "support_level", "GENCODE", "Transcript support level indicates weak support",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "tsl5", "support_level", "GENCODE", "Transcript support level indicates poor support",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "tslNA", "support_level", "GENCODE", "Transcript support level is not applicable",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "basic", "tag", "GENCODE", "Transcript belongs to the basic annotation subset",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "canonical", "tag", "Ensembl", "Transcript is selected as canonical for the gene",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "readthrough_transcript", "tag", "GENCODE", "Transcript spans neighboring loci in a readthrough model",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "retained_intron", "tag", "GENCODE", "Transcript includes a retained intron annotation",
      "GTF transcript attributes",
    ),
    evidence_ref(
      "cds_start_NF", "tag", "GENCODE", "Coding start is not finished", "CDS attributes",
    ),
    evidence_ref(
      "cds_end_NF", "tag", "GENCODE", "Coding end is not finished", "CDS attributes",
    ),
    evidence_ref(
      "mrna_start_NF", "tag", "GENCODE", "Transcript start is not finished", "transcript attributes",
    ),
    evidence_ref(
      "mrna_end_NF", "tag", "GENCODE", "Transcript end is not finished", "transcript attributes",
    ),
    evidence_ref(
      "nonsense_mediated_decay", "tag", "GENCODE", "Transcript is annotated as an NMD candidate",
      "transcript attributes",
    ),
    evidence_ref(
      "low_confidence", "quality", "generic", "Feature has weak or conflicting support",
      "quality filtering",
    ),
    evidence_ref(
      "high_confidence", "quality", "generic", "Feature has strong support from available evidence",
      "quality filtering",
    ),
    evidence_ref(
      "partial", "quality", "generic", "Feature is known to be incomplete", "partial gene models",
    ),
    evidence_ref(
      "complete", "quality", "generic", "Feature has complete expected boundaries",
      "complete gene models",
    ),
    evidence_ref(
      "validated", "quality", "generic", "Feature passed provider-specific validation",
      "release checks",
    ),
    evidence_ref(
      "deprecated", "lifecycle", "generic", "Feature is retained only for compatibility",
      "legacy releases",
    ),
    evidence_ref(
      "withdrawn", "lifecycle", "generic", "Feature has been removed from current annotation",
      "release migration",
    ),
    evidence_ref(
      "merged_into", "lifecycle", "generic", "Feature identity was merged into another feature",
      "release migration",
    ),
    evidence_ref(
      "split_from", "lifecycle", "generic", "Feature identity was split from a previous feature",
      "release migration",
    ),
  ]
}

///|
pub fn find_evidence_reference(code : String) -> EvidenceReference {
  for item in evidence_references() {
    if item.code == code {
      return item
    }
  }
  evidence_ref(
    code, "custom", "project", "Project-specific evidence label", "local annotation",
  )
}

///|
pub fn evidence_references_by_category(
  category : String,
) -> Array[EvidenceReference] {
  let result : Array[EvidenceReference] = []
  for item in evidence_references() {
    if item.category == category {
      result.push(item)
    }
  }
  result
}

///|
pub fn evidence_references_by_source(
  source : String,
) -> Array[EvidenceReference] {
  let result : Array[EvidenceReference] = []
  for item in evidence_references() {
    if item.source == source {
      result.push(item)
    }
  }
  result
}

///|
pub fn EvidenceReference::to_tsv_row(self : EvidenceReference) -> String {
  [self.code, self.category, self.source, self.description, self.typical_scope].join(
    "\t",
  )
}