///|
/// mmseqs2 风格本地蛋白质搜索演示: 合成激酶家族库 → k-mer 索引 →
/// prefilter(ungapped x-drop) → SW 精化 + E-value → linclust 预聚类.
fn main raise {
  let rng = @src.Rng::from_int(42)
  let aas = "ACDEFGHIKLMNPQRSTVWY"
  // 1. 合成库: 15 条激酶家族(Walker-A motif 嵌入随机背景) + 85 条随机
  let db = @src.MmseqsDB::new()
  for i in 0..<15 {
    let bg = StringBuilder()
    for _j in 0..<30 {
      bg.write_char(aas.unsafe_get(rng.next_int(20)).unsafe_to_char())
    }
    let ed = StringBuilder()
    for _j in 0..<30 {
      ed.write_char(aas.unsafe_get(rng.next_int(20)).unsafe_to_char())
    }
    ignore(
      db.add(
        "MK" + bg.to_string() + "GHVDHGKTT" + ed.to_string() + "LMNL",
        id="kinase" + i.to_string(),
      ),
    )
  }
  for i in 0..<85 {
    let rs = StringBuilder()
    for _j in 0..<60 {
      rs.write_char(aas.unsafe_get(rng.next_int(20)).unsafe_to_char())
    }
    ignore(db.add(rs.to_string(), id="rand" + i.to_string()))
  }
  let query = "MKTGHVDHGKTTLKMNLVEG"
  println("=== mmseqs2 风格蛋白质搜索 (库 100 条, k=6) ===")
  println("  库残基总数: " + db.total_residues().to_string())
  // 2. 建索引
  let idx = @src.MmseqsIndex::build(db, k=6)
  println(
    "  k-mer 索引: " +
    idx.num_kmers().to_string() +
    " 个不同 6-mer, k=" +
    idx.k().to_string(),
  )
  // 3. prefilter: ungapped x-drop 快速筛查
  let pre = @src.mmseqs_prefilter(idx, query)
  println("=== prefilter (ungapped x-drop, 分数降序 top5) ===")
  let top_n = if pre.length() < 5 { pre.length() } else { 5 }
  for i in 0.. 0 {
    println("=== 最优命中比对 ===")
    println(hits[0].format())
  }
  // 5. 预聚类(独立演示库: 10 个"物种"基序列 × 各 10 条近重复拷贝,
  //    linclust 的本用途是去冗余而非远程同源聚类)
  let cdb = @src.MmseqsDB::new()
  for s in 0..<10 {
    let base = StringBuilder()
    for _j in 0..<50 {
      base.write_char(aas.unsafe_get(rng.next_int(20)).unsafe_to_char())
    }
    let bs = base.to_string()
    for c in 0..<10 {
      let arr : Array[Int32] = []
      for ch in bs {
        arr.push(ch.to_int())
      }
      let mpos = rng.next_int(arr.length())
      arr[mpos] = aas.unsafe_get(rng.next_int(20)).to_int()
      let sb = StringBuilder()
      for v in arr {
        sb.write_char(v.unsafe_to_char())
      }
      ignore(
        cdb.add(sb.to_string(), id="sp" + s.to_string() + "_" + c.to_string()),
      )
    }
  }
  // 代表自身含 1 突变 + 拷贝 1 突变 → 拷贝与代表差 2 位,
  // shared ≈ 33/45 ≈ 0.73, coverage 取 0.7
  let assign = @src.mmseqs_cluster(cdb, coverage=0.7)
  let mut nclusters = 0
  for a in assign {
    if a + 1 > nclusters {
      nclusters = a + 1
    }
  }
  let mut first_size = 0
  for a in assign {
    if a == assign[0] {
      first_size = first_size + 1
    }
  }
  println("=== linclust 风格预聚类 (10 物种 × 10 近重复拷贝) ===")
  println(
    "  100 条序列 → " +
    nclusters.to_string() +
    " 簇; 首簇 " +
    first_size.to_string() +
    " 条 (coverage=0.7)",
  )
  println("")
  println(
    "注: 本模块为 mmseqs2 风格筛查级实现(5bit 精确 k-mer/单点对角",
  )
  println("    延伸/ungapped 统计 E-value), 非其替身.")
}