///|
/// missMethyl demo - Differential methylation analysis with GO enrichment.
///
/// Demonstrates beta/M-value conversion, DMP analysis with BH-FDR correction,
/// gene-level GO enrichment, probe-bias-corrected GO enrichment, probe
/// filtering, and textual summaries.
///
/// Reference: Phipson B, Maksimovic J, Oshlack A (2016) missMethyl: an R
/// package for analyzing data from Illumina's HumanMethylation450 platform.
/// Bioinformatics 32(2):286-288.
/// Run: moon run examples/missmethyl_demo
fn main {
  println("=== missMethyl Demo ===")
  println("Differential methylation analysis with GO enrichment")
  println("")

  // ------------------------------------------------------------------
  // 1. Load sample annotations, GO database, and beta-value matrix
  // ------------------------------------------------------------------
  println("=== 1. Load sample data ===")
  let annotations = @bio.mm_sample_annotations()
  let go_db = @bio.mm_sample_go_database()
  let beta = @bio.mm_sample_beta()
  let group : Array[Bool] = [false, false, false, false, true, true, true, true]
  println("Loaded \{annotations.length()} probe annotations")
  println(
    "Loaded \{beta.length()} probes x \{beta[0].length()} samples beta matrix",
  )
  println("Group: 4 control (false) + 4 treatment (true)")
  println("")

  // ------------------------------------------------------------------
  // 2. Beta/M value conversion examples
  // ------------------------------------------------------------------
  println("=== 2. Beta/M value conversions ===")
  let betas : Array[Double] = [0.1, 0.25, 0.5, 0.75, 0.9]
  for b in betas {
    let m = @bio.mm_beta_to_m(b)
    let b_back = @bio.mm_m_to_beta(m)
    println(
      "  beta=" +
      b.to_string() +
      " -> M=" +
      m.to_string() +
      " -> beta(back)=" +
      b_back.to_string(),
    )
  }
  // Edge cases: clamping
  let m0 = @bio.mm_beta_to_m(0.0)
  let m1 = @bio.mm_beta_to_m(1.0)
  println("  beta=0.0 (clamped) -> M=" + m0.to_string())
  println("  beta=1.0 (clamped) -> M=" + m1.to_string())
  println("")

  // ------------------------------------------------------------------
  // 3. DMP analysis (limma-style t-test on M-values + BH-FDR)
  // ------------------------------------------------------------------
  println("=== 3. Differential Methylation Position (DMP) analysis ===")
  let dmp_results = @bio.mm_dmp_analysis(beta, group, annotations)
  let mut n_sig_05 = 0
  let mut n_sig_01 = 0
  for r in dmp_results {
    if r.is_significant(0.05) {
      n_sig_05 = n_sig_05 + 1
    }
    if r.is_significant(0.01) {
      n_sig_01 = n_sig_01 + 1
    }
  }
  println("Total probes tested: \{dmp_results.length()}")
  println("Significant (adj p < 0.05): \{n_sig_05}")
  println("Significant (adj p < 0.01): \{n_sig_01}")
  println("")

  // Manual bubble sort by adjusted p-value (ascending) for display.
  let sorted = dmp_results.copy()
  let n = sorted.length()
  let mut i = 0
  while i < n - 1 {
    let mut j = 0
    while j < n - 1 - i {
      if sorted[j].adj_p_value() > sorted[j + 1].adj_p_value() {
        let tmp = sorted[j]
        sorted[j] = sorted[j + 1]
        sorted[j + 1] = tmp
      }
      j = j + 1
    }
    i = i + 1
  }
  println("Top 5 DMPs by significance:")
  let top_n = if n < 5 { n } else { 5 }
  for k in 0..