///|
/// 融合基因 caller 演示: SAM SA 标签 -> split-read 断点簇 -> 融合候选.
fn main raise {
  println(
    "=== 融合基因 caller (split-read 断点簇, STAR-Fusion 风格) ===",
  )

  // 模拟 SAM: 6 条 split read
  // split1-3: chr1:1016 -- chr2:5016 (融合 A, 支持 3)
  // split4-5: chr1:2016 -- chr2:8016 (融合 B, 支持 2)
  // split6: 单读(低于支持阈值)
  let sam_header = "@HD\tVN:1.6\tSO:coordinate\n@SQ\tSN:chr1\tLN:1000000\n@SQ\tSN:chr2\tLN:1000000\n"
  let mk = fn(
    qname : String,
    chrom : String,
    pos : Int32,
    sa : String,
  ) -> String {
    qname +
    "\t0\t" +
    chrom +
    "\t" +
    pos.to_string() +
    "\t60\t16M16S\t*\t0\t0\tACGTACGTACGTACGTACGTACGTACGTACGT\tIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII\tSA:Z:" +
    sa
  }
  let reads : Array[String] = [
    mk("split1", "chr1", 1000, "chr2,5000,+,16S16M,60,0;"),
    mk("split2", "chr1", 1000, "chr2,5000,+,16S16M,60,0;"),
    mk("split3", "chr1", 1005, "chr2,5005,+,16S16M,60,0;"),
    mk("split4", "chr1", 2000, "chr2,8000,+,16S16M,60,0;"),
    mk("split5", "chr1", 2000, "chr2,8000,+,16S16M,60,0;"),
    mk("split6", "chr1", 5000, "chr2,9000,+,16S16M,60,0;"),
  ]
  let sb = StringBuilder()
  sb.write_string(sam_header)
  sb.write_char('\n')
  for r in reads {
    sb.write_string(r)
    sb.write_char('\n')
  }
  let sam = sb.to_string()
  println("SAM 输入: \{reads.length()} 条 split read")

  // 1. 断点对提取
  println("\n1. split-read 断点对提取(SA 标签)")
  let js = @src.fusion_junctions_from_sam(sam)
  println("  共 \{js.length()} 个 junction")
  for j in js {
    println(
      "  \{j.qname}: \{j.chrom_a}:\{j.break_a} -- \{j.chrom_b}:\{j.break_b}",
    )
  }

  // 2. 断点簇聚类与候选
  println("\n2. 融合候选(断点簇, min_support=2)")
  let candidates = @src.fusion_call(js, min_support=2)
  println("  " + @src.fusion_candidates_summary(candidates))
  for c in candidates {
    println("  " + c.summary())
  }

  // 3. read-through 过滤演示
  println("\n3. read-through 过滤(同链近距)")
  let rt_js : Array[@src.FusionJunction] = []
  for i = 0; i < 5; i = i + 1 {
    rt_js.push({
      qname: "rt" + i.to_string(),
      chrom_a: "chr1",
      break_a: 100000,
      strand_a: 0,
      chrom_b: "chr1",
      break_b: 150000,
      strand_b: 0,
    })
  }
  let rt_candidates = @src.fusion_call(
    rt_js,
    min_support=2,
    readthrough_max=200000,
  )
  for c in rt_candidates {
    println("  " + c.summary() + " (被过滤)")
  }

  // 4. TSV 输出
  println("\n4. STAR-Fusion 风格 TSV")
  let tsv = @src.fusion_write_tsv(candidates)
  let lines = tsv.split("\n").to_array()
  for l in lines {
    let s = l.to_owned()
    if s.length() > 0 {
      println("  " + s)
    }
  }

  // 5. BEDPE 输出(与 parse_bedpe 闭环)
  println("\n5. BEDPE 输出(与 bedpe.mbt 闭环)")
  let bedpe = @src.fusion_write_bedpe(candidates)
  let content_lines = bedpe.split("\n").to_array()
  let filtered : Array[String] = []
  for l in content_lines {
    let s = l.to_owned()
    if s.length() > 0 && !s.has_prefix("#") {
      filtered.push(s)
    }
  }
  let joined : String = filtered.join("\n") + "\n"
  let pairs = @src.parse_bedpe(joined)
  println("  BEDPE 解析: \{pairs.length()} 条记录闭环")

  println(
    "\n完成: SA 解析 -> 断点簇 -> 融合候选 -> TSV/BEDPE 全链路本地完成.",
  )
}