///|
/// MutationalPatterns module example - Somatic mutation pattern analysis.
///
/// Run: moon run examples/mutational_patterns_demo
fn main {
  println("=== MutationalPatterns Module Demo ===")
  println("Somatic Mutation Pattern Analysis (96-channel)")
  println("")

  // ---- Section 1: Mutation categories ----
  println("=== 1. Mutation Categories (Pyrimidine-based) ===")
  let types = @bio.all_mutation_types()
  println("Total categories: " + types.length().to_string())
  let mut ti = 0
  while ti < types.length() {
    println("  " + types[ti].to_string())
    ti = ti + 1
  }
  println("")

  // ---- Section 2: Trinucleotide contexts ----
  println("=== 2. Trinucleotide Contexts ===")
  let contexts = @bio.trinucleotide_contexts()
  println("Total contexts: " + contexts.length().to_string())
  let mut ci = 0
  while ci < contexts.length() {
    println("  " + contexts[ci])
    ci = ci + 1
  }
  println("")

  // ---- Section 3: Channel labels (96 channels) ----
  println("=== 3. 96-Channel Labels ===")
  let labels = @bio.get_channel_labels()
  println("Total channels: " + labels.length().to_string())
  // Show first 6 and last 6 labels
  println(
    "First 6: " +
    labels[0] +
    ", " +
    labels[1] +
    ", " +
    labels[2] +
    ", " +
    labels[3] +
    ", " +
    labels[4] +
    ", " +
    labels[5],
  )
  println(
    "Last 6:  " +
    labels[90] +
    ", " +
    labels[91] +
    ", " +
    labels[92] +
    ", " +
    labels[93] +
    ", " +
    labels[94] +
    ", " +
    labels[95],
  )
  println("")

  // ---- Section 4: Mutation type detection ----
  println("=== 4. Mutation Type Detection ===")
  // C>T transition
  let mtype_ct = @bio.get_mutation_type("C", "T")
  println("  C>T -> " + mtype_ct.to_string())
  // G>A should be reverse-complemented to C>T (pyrimidine-based)
  let mtype_ga = @bio.get_mutation_type("G", "A")
  println("  G>A -> " + mtype_ga.to_string() + " (pyrimidine-equivalent)")
  // C>A transversion
  let mtype_ca = @bio.get_mutation_type("C", "A")
  println("  C>A -> " + mtype_ca.to_string())
  println("")

  // ---- Section 5: Context normalization ----
  println("=== 5. Trinucleotide Context Normalization ===")
  // ACT (middle is C, pyrimidine) -> stays as ACT
  let norm1 = @bio.normalize_context("ACT")
  println("  ACT -> " + norm1 + " (pyrimidine middle, unchanged)")
  // AGT (middle is G, purine) -> reverse complement -> ACT
  let norm2 = @bio.normalize_context("AGT")
  println("  AGT -> " + norm2 + " (purine middle, reverse-complemented)")
  println("")

  // ---- Section 6: Build mutation matrix ----
  println("=== 6. Build 96-channel Mutation Matrix ===")
  let mutations = @bio.mutational_patterns_sample_data()
  let sample_ids = ["S1", "S2"]
  let matrix = @bio.build_mutation_matrix(mutations, sample_ids)
  println("Samples: " + matrix.sample_ids.length().to_string())
  println("Channels: " + matrix.channel_labels.length().to_string())
  let mut si = 0
  while si < matrix.sample_ids.length() {
    println(
      "  " +
      matrix.sample_ids[si] +
      ": " +
      matrix.total_mutations[si].to_string() +
      " total mutations",
    )
    si = si + 1
  }
  println("")

  // ---- Section 7: Mutation spectrum summary ----
  println("=== 7. Mutation Spectrum Summary ===")
  let summary = matrix.spectrum_summary()
  println(summary)
  println("")

  // ---- Section 8: Sample-sample cosine similarity ----
  println("=== 8. Cosine Similarity Between Samples ===")
  let sim_same = matrix.sample_cosine_similarity(0, 0)
  let sim_diff = matrix.sample_cosine_similarity(0, 1)
  println("  S1 vs S1 (identical): " + sim_same.to_string())
  println("  S1 vs S2 (different): " + sim_diff.to_string())
  println("")

  // ---- Section 9: Relative frequencies ----
  println("=== 9. Relative Mutation Frequencies (per sample) ===")
  let freqs = matrix.to_relative_frequencies()
  let mut sum0 = 0.0
  let mut fi = 0
  while fi < 96 {
    sum0 = sum0 + freqs[fi][0]
    fi = fi + 1
  }
  println("  Sum of S1 frequencies (should be ~1.0): " + sum0.to_string())
  println("")

  // ---- Section 10: COSMIC signatures and signature fitting ----
  println("=== 10. Known COSMIC Signatures ===")
  let sigs = @bio.known_cosmic_signatures()
  let mut sj = 0
  while sj < sigs.length() {
    let sig = sigs[sj]
    let mut total = 0.0
    let mut pi = 0
    while pi < sig.probabilities.length() {
      total = total + sig.probabilities[pi]
      pi = pi + 1
    }
    println(
      "  " +
      sig.id +
      ": " +
      sig.probabilities.length().to_string() +
      " channels, total prob = " +
      total.to_string(),
    )
    sj = sj + 1
  }
  println("")

  // ---- Section 11: Fit signatures to a sample ----
  println("=== 11. Fit Signatures to Sample S1 ===")
  // Use S1 frequencies as sample profile
  let s1_profile : Array[Double] = Array(capacity=0)
  let mut pp = 0
  while pp < 96 {
    s1_profile.push(freqs[pp][0])
    pp = pp + 1
  }
  let contributions = @bio.fit_signatures(s1_profile, sigs)
  println("Signature contributions:")
  let mut ck = 0
  while ck < contributions.length() {
    println("  " + sigs[ck].id + ": " + contributions[ck].to_string())
    ck = ck + 1
  }
  let mut total_contrib = 0.0
  let mut tk = 0
  while tk < contributions.length() {
    total_contrib = total_contrib + contributions[tk]
    tk = tk + 1
  }
  println("  Total (should be ~1.0): " + total_contrib.to_string())
  println("")

  // ---- Section 12: Channel index lookup ----
  println("=== 12. Channel Index Lookup ===")
  let idx1 = @bio.get_channel_index("C", "T", "ACT")
  let idx2 = @bio.get_channel_index("C", "A", "CCA")
  println("  C>T at ACT context -> channel " + idx1.to_string())
  println("  C>A at CCA context -> channel " + idx2.to_string())
  println("")

  println("=== Demo complete ===")
}