///|
/// Sequence alignment example: global & local pairwise alignment.
///
/// Demonstrates Needleman-Wunsch (global) and Smith-Waterman (local)
/// alignment algorithms for both DNA and protein sequences.
///
/// Run: moon run examples/alignment_demo/main.mbt
fn main {
  // === Global pairwise alignment (Needleman-Wunsch) ===
  let dna1 = @bio.DNA::new("ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG")
  let dna2 = @bio.DNA::new("ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAC")

  let (msa_global, score_g, start_g, end_g) = @bio.global_pairwise_align_nucleotide(
    dna1, dna2,
  )
  println("=== Global Pairwise Alignment (Needleman-Wunsch) ===")
  println("  Score: \{score_g}")
  println("  Start: \{Repr(start_g)}")
  println("  End:   \{Repr(end_g)}")
  let recs = msa_global.records
  for i = 0; i < recs.length(); i = i + 1 {
    println("  Seq \{i}: \{recs[i].seq.to_string()}")
  }

  // === Local pairwise alignment (Smith-Waterman) ===
  let (msa_local, score_l, start_l, end_l) = @bio.local_pairwise_align_nucleotide(
    dna1, dna2,
  )
  println("\n=== Local Pairwise Alignment (Smith-Waterman) ===")
  println("  Score: \{score_l}")
  println("  Start: \{Repr(start_l)}")
  println("  End:   \{Repr(end_l)}")
  let local_recs = msa_local.records
  for i = 0; i < local_recs.length(); i = i + 1 {
    println("  Seq \{i}: \{local_recs[i].seq.to_string()}")
  }

  // === Protein alignment ===
  let prot1 = @bio.Protein::new("MKKLLLISVLLFLSSAYSR")
  let prot2 = @bio.Protein::new("MKKLLLISVLLFLSSAYSQ")

  let (prot_msa, prot_score, _, _) = @bio.global_pairwise_align_protein(
    prot1, prot2,
  )
  println("\n=== Protein Global Alignment ===")
  println("  Score: \{prot_score}")
  let p_recs = prot_msa.records
  for i = 0; i < p_recs.length(); i = i + 1 {
    println("  Seq \{i}: \{p_recs[i].seq.to_string()}")
  }

  // === Parse Clustal alignment ===
  let clustal = "CLUSTAL X (1.81) multiple sequence alignment\n\n\nseq1                          ATGCCGATCGATCGATCGAT\nseq2                          ATGCCGATCGATCGATCGAT\nseq3                          ATGCCGATCGATCGATCGAT\n"

  try {
    let align = @bio.parse_clustal(clustal)
    println("\n=== Clustal Alignment ===")
    println("  Records: \{align.num_records()}")
    println("  Length:   \{align.get_alignment_length()}")

    // === Write Clustal ===
    let clustal_out = @bio.write_clustal(align)
    println("\n=== Clustal Output ===")
    println(clustal_out)
  } catch {
    _ => println("Clustal error occurred")
  }

  // === Parse Phylip ===
  let phylip = " 3 20\nseq1       ATGCCGATCG ATCGATCGAT \nseq2       ATGCCGATCG ATCGATCGAT \nseq3       ATGCCGATCG ATCGATCGAT \n"
  try {
    let phy_align = @bio.parse_phylip(phylip)
    println("=== Phylip Alignment ===")
    println("  Records: \{phy_align.num_records()}")
  } catch {
    _ => println("Phylip error occurred")
  }

  // === TabularMSA consensus & conservation ===
  let dna_arr = [
    @bio.DNA::new("ATGC"),
    @bio.DNA::new("ATGC"),
    @bio.DNA::new("ATGT"),
  ]
  let tab_msa = @bio.TabularMSA::from_dna(dna_arr)
  let consensus = tab_msa.consensus()
  let conservation = tab_msa.conservation()
  println("\n=== TabularMSA ===")
  println("  Consensus: \{consensus.to_string()}")
  println("  Conservation: \{Repr(conservation)}")
}