///|
/// FBA 代谢建模演示: toy 模型 -> 通量求解 -> 基因敲除筛查.
fn main raise {
  println("=== FBA 代谢通量平衡分析 (cobra-lite 单纯形) ===")

  // toy 模型: (外) -R0-> A -R1-> B -R2-> C -R3->(外排)
  //                                  C -R4-> biomass
  let mut model = @src.fba_model_new(["A", "B", "C"])
  model = model.add_reaction(
    {
      id: "R0",
      name: "uptake",
      lower_bound: 0.0,
      upper_bound: 10.0,
      objective: 0.0,
      genes: ["geneU"],
    },
    [("A", 1.0)],
  )
  model = model.add_reaction(
    {
      id: "R1",
      name: "A_to_B",
      lower_bound: 0.0,
      upper_bound: 1000.0,
      objective: 0.0,
      genes: ["geneA"],
    },
    [("A", -1.0), ("B", 1.0)],
  )
  model = model.add_reaction(
    {
      id: "R2",
      name: "B_to_C",
      lower_bound: 0.0,
      upper_bound: 1000.0,
      objective: 0.0,
      genes: ["geneB"],
    },
    [("B", -1.0), ("C", 1.0)],
  )
  model = model.add_reaction(
    {
      id: "R3",
      name: "excrete",
      lower_bound: 0.0,
      upper_bound: 1000.0,
      objective: 0.0,
      genes: ["geneE"],
    },
    [("C", -1.0)],
  )
  model = model.add_reaction(
    {
      id: "R4",
      name: "biomass",
      lower_bound: 0.0,
      upper_bound: 1000.0,
      objective: 1.0,
      genes: [],
    },
    [("C", -1.0)],
  )

  // 1. 野生型 FBA
  println("\n1. 野生型 FBA(底物上界 10)")
  let wt = @src.fba_solve(model)
  println("  " + wt.summary(model))
  for j = 0; j < model.reactions.length(); j = j + 1 {
    let r = model.reactions[j]
    println("  \{r.id}(\{r.name}): \{wt.fluxes[j]}")
  }

  // 2. 底物限制
  println("\n2. 底物限制(上界 10 -> 2.5)")
  // 底物限制: uptake 上界 10 -> 2.5
  let limited = @src.fba_set_reaction_bound(model, "R0", 0.0, 2.5)
  let lim_sol = @src.fba_solve(limited)
  println("  biomass = \{lim_sol.objective_value} (应随底物线性: 2.5)")

  // 3. 基因敲除筛查
  println("\n3. 基因敲除表型筛查")
  let screen = @src.fba_knockout_screen(model)
  for row in screen {
    println("  \{row.0}: biomass=\{row.1} -> \{row.2}")
  }

  // 4. JSON 模型交换
  println("\n4. JSON 模型交换(roundtrip)")
  let json = @src.fba_write_json(model)
  println("  \{json.length()} 字符")
  let reparsed = @src.fba_parse_json(json)
  match reparsed {
    Some(m) => {
      let sol2 = @src.fba_solve(m)
      println(
        "  reparsed: \{m.reactions.length()} 反应, biomass=\{sol2.objective_value} (与原模型一致)",
      )
    }
    None => println("  reparsed FAILED")
  }

  // 5. 经典 LP 验证
  println("\n5. 经典 LP 验证(单纯形正确性)")
  let a : Array[Array[Double]] = [[3.0, 2.0, 1.0]]
  let b : Array[Double] = [18.0]
  let c : Array[Double] = [3.0, 5.0, 0.0]
  let ub : Array[Double] = [4.0, 6.0, 1000.0]
  match @src.fba_solve_lp(a, b, c, ub) {
    Some((obj, _)) =>
      println("  max 3x1+5x2 (3x1+2x2<=18, x1<=4, x2<=6) = \{obj} (期望 36)")
    None => println("  LP FAILED")
  }

  println(
    "\n完成: 模型构造 -> 单纯形求解 -> 敲除筛查 -> JSON 交换全链路本地完成.",
  )
}