///|
/// 宏基因组物种丰度定量演示(Kraken/Bracken 风格):
/// 分类树 + 参考基因组 -> k-mer LCA 库 -> 读段分类 -> 丰度报告.
fn main {
  println("=== 宏基因组物种丰度定量 (Kraken/Bracken-lite) ===")

  // 分类树.
  let taxa : Array[@src.KrakenTaxon] = [
    @src.kraken_taxon_new("1", "root", "root", None),
    @src.kraken_taxon_new("10", "Alpha", "genus", Some("1")),
    @src.kraken_taxon_new("11", "Alpha one", "species", Some("10")),
    @src.kraken_taxon_new("12", "Alpha two", "species", Some("10")),
    @src.kraken_taxon_new("20", "Beta", "genus", Some("1")),
    @src.kraken_taxon_new("21", "Beta one", "species", Some("20")),
  ]

  // 参考基因组(k=5).
  let references : Array[@src.KrakenReference] = [
    @src.kraken_reference_new("11", "ACGTAACCGGTT"),
    @src.kraken_reference_new("12", "ACGTAACCGGAA"),
    @src.kraken_reference_new("21", "TTTTGGGGCCCCAAAA"),
  ]
  let db = @src.kraken_build_database(5, taxa, references) catch {
    KrakenLiteError(message) => {
      println("建库失败: " + message)
      return
    }
  }
  println("\nk = \{db.k}, 分类单元数 = \{db.taxa.length()}")

  // 模拟读段: Alpha one x3, 属级共享 x1, Beta one x2.
  let reads : Map[String, String] = Map([
    ("r1", "ACGTAACCGGTT"),
    ("r2", "ACGTAACCGGTT"),
    ("r3", "ACGTAACCGGTT"),
    ("r4", "ACGTAACCGG"),
    ("r5", "TTTTGGGGCCCCAAAA"),
    ("r6", "TTTTGGGGCCCCAAAA"),
  ])
  let results = @src.kraken_classify_many(db, reads)
  println("\n1. 逐读段分类")
  for result in results {
    let taxid = match result.taxid {
      Some(value) => value
      None => "-"
    }
    println(
      "  \{result.name}: taxid=\{taxid}, rank=\{result.rank}, 支持=\{result.hits}/\{result.total_kmers}, 置信度=\{result.confidence}",
    )
  }

  println("\n2. Kraken 风格种级报告(累计计数)")
  let species = @src.kraken_report(db, results, "species")
  println(@src.kraken_abundance_tsv(species))

  println(
    "3. Bracken 风格种级重分摊(属级读段按 k-mer 支持度下推)",
  )
  let bracken = @src.kraken_bracken(db, results, "species")
  println(@src.kraken_abundance_tsv(bracken))

  println("4. JSON 输出")
  println(@src.kraken_abundance_json(db, bracken))

  println("\n5. minimizer 建库(内存压缩)")
  let mini = @src.kraken_build_database_minimizer(5, 4, taxa, references) catch {
    KrakenLiteError(message) => {
      println("minimizer 建库失败: " + message)
      return
    }
  }
  println(
    "  精确库索引项 = \{db.kmer_lca.length()}, minimizer(w=4) 索引项 = \{mini.kmer_lca.length()}",
  )
  let mini_read = @src.kraken_classify(mini, "r5", "TTTTGGGGCCCCAAAA")
  let mini_taxid = match mini_read.taxid {
    Some(value) => value
    None => "-"
  }
  println(
    "  minimizer 分类 r5 -> taxid=\{mini_taxid}, rank=\{mini_read.rank}",
  )

  println("\n6. 数据库 JSON 序列化 / roundtrip")
  let db_json = @src.kraken_database_to_json(mini)
  println("  序列化长度 = \{db_json.length()} 字节")
  match @src.kraken_database_from_json(db_json) {
    Some(restored) =>
      println(
        "  还原: k=\{restored.k}, minimizer_w=\{restored.minimizer_w}, 索引项=\{restored.kmer_lca.length()}",
      )
    None => println("  roundtrip 失败")
  }

  println("\n7. HTML/SVG 报告")
  let html = @src.kraken_report_html(bracken, title="Kraken-lite Demo")
  println(
    "  HTML 长度 = \{html.length()} 字节, 含  = \{html.contains("