///|
/// gVCF 参考块 / 多样本合并 / 联合基因分型演示.
///
/// 流程: 两个样本各自的变异 -> 单样本 gVCF(变异记录 + 参考块) -> 合并 ->
/// 联合基因分型 -> 多样本 VCF + JSON.

///|
fn gvcf_demo_ref() -> String {
  "ATCGGATTCAGCCTAGGATCAAGTTCGGATACCTAGGCATTGCAAGGTCCTAGAAGT"
}

///|
fn gvcf_demo_read(
  reference : String,
  pos : Int32,
  offset : Int32?,
  alt : Char,
  name : String,
) -> @src.GatkRead {
  let end = if pos + 20 < reference.length() {
    pos + 20
  } else {
    reference.length()
  }
  let mut seq = reference[pos:end].to_owned()
  match offset {
    Some(off) =>
      if off >= 0 && off < seq.length() {
        seq = seq[0:off].to_owned() + alt.to_string() + seq[off + 1:].to_owned()
      }
    None => ()
  }
  { name, seq, pos, }
}

///|
fn gvcf_demo_sample_variants(
  reference : String,
  start : Int32,
  offset : Int32,
  alt : Char,
  sample : String,
) -> Array[@src.GatkVariant] {
  let reads : Array[@src.GatkRead] = []
  for i = 0; i < 10; i = i + 1 {
    let off : Int32? = if i < 5 { Some(offset) } else { None }
    reads.push(
      gvcf_demo_read(reference, start, off, alt, sample + "_r" + i.to_string()),
    )
  }
  @src.gatk_call_variants("chr1", reference, reads)
}

///|
fn gvcf_demo_show(callset : @src.GvcfCallset) -> Unit {
  for record in callset.records {
    if record.is_block {
      println(
        "  [block]   \{record.chrom}:\{record.pos}-\{record.block_end} ref=\{record.ref_allele} ",
      )
    } else {
      let alts = StringBuilder()
      for i, alt in record.alts {
        if i > 0 {
          alts.write_char(',')
        }
        alts.write_string(alt)
      }
      let mut sample_note = ""
      for s in callset.samples {
        match record.samples.get(s) {
          Some(g) => sample_note = sample_note + " " + s + "=" + g.gt
          None => ()
        }
      }
      println(
        "  [variant] \{record.chrom}:\{record.pos} ref=\{record.ref_allele} alt=\{alts.to_string()}\{sample_note}",
      )
    }
  }
}

///|
fn main {
  println("=== gVCF 参考块 / 多样本合并 / 联合基因分型 ===")
  let reference = gvcf_demo_ref()
  println("参考长度: \{reference.length()}")

  let variants_s1 = gvcf_demo_sample_variants(reference, 10, 5, 'C', "S1")
  let variants_s2 = gvcf_demo_sample_variants(reference, 20, 4, 'C', "S2")
  println("\n样本 S1 检出变异: \{variants_s1.length()}")
  println("样本 S2 检出变异: \{variants_s2.length()}")

  let cs1 = @src.gvcf_build_from_variants(
    "chr1",
    reference,
    variants_s1,
    sample="S1",
  ) catch {
    @src.GvcfError(message) => {
      println("S1 gVCF 构建失败: " + message)
      return
    }
  }
  let cs2 = @src.gvcf_build_from_variants(
    "chr1",
    reference,
    variants_s2,
    sample="S2",
  ) catch {
    @src.GvcfError(message) => {
      println("S2 gVCF 构建失败: " + message)
      return
    }
  }
  println("\n1. 单样本 gVCF (S1)")
  gvcf_demo_show(cs1)
  println("  摘要: \{@src.gvcf_summary(cs1)}")
  println("\n   单样本 gVCF (S2)")
  gvcf_demo_show(cs2)
  println("  摘要: \{@src.gvcf_summary(cs2)}")

  let merged = @src.gvcf_merge([cs1, cs2]) catch {
    @src.GvcfError(message) => {
      println("合并失败: " + message)
      return
    }
  }
  println(
    "\n2. 多样本合并(未覆盖到变异的样本按参考块判为 0/0)",
  )
  for record in merged.records {
    let mut note = ""
    for s in merged.samples {
      match record.samples.get(s) {
        Some(g) => note = note + " " + s + "=" + g.gt
        None => ()
      }
    }
    println("  \{record.chrom}:\{record.pos} ref=\{record.ref_allele} \{note}")
  }

  let joint = @src.gvcf_joint_genotype(merged)
  println("\n3. 联合基因分型(按各样本 PL 重算 GT)")
  for record in joint.records {
    let mut note = ""
    for s in joint.samples {
      match record.samples.get(s) {
        Some(g) =>
          note = note + " " + s + "=" + g.gt + "(GQ=" + g.gq.to_string() + ")"
        None => ()
      }
    }
    println("  \{record.chrom}:\{record.pos} ref=\{record.ref_allele} \{note}")
  }

  println("\n4. 多样本 VCF 输出")
  println(@src.gvcf_write_vcf(joint))

  println("5. JSON 序列化 / roundtrip")
  let json = @src.gvcf_callset_to_json(joint)
  println("  JSON 长度 = \{json.length()} 字节")
  match @src.gvcf_callset_from_json(json) {
    Some(restored) =>
      println(
        "  还原: samples=\{restored.samples.length()}, records=\{restored.records.length()}",
      )
    None => println("  roundtrip 失败")
  }

  println(
    "\n演示完成: gVCF 参考块 + 多样本合并 + 联合基因分型闭环",
  )
}