///|
fn main {
  println("==================================================")
  println(
    "   MoonSim 分布式系统网络仿真示例:Raft心跳与网络分区   ",
  )
  println("==================================================")

  let sim = @moonsim.Simulation::new()
  let topo : @network.NetworkTopology[String] = sim.create_network_topology(
    20260708,
  )

  topo.add_node(1) // Leader
  topo.add_node(2) // Follower A
  topo.add_node(3) // Follower B

  // Links with 0.01s (10ms) latency and 0.05 (5%) drop probability
  topo.add_link(1, 2, 0.01, 0.05)
  topo.add_link(1, 3, 0.01, 0.05)

  let mut heartbeat_seq = 1

  // Periodic Leader Heartbeat process
  let steps : Array[(@event.ProcessContext) -> Double?] = [
    fn(ctx : @event.ProcessContext) -> Double? {
      if ctx.clock.now_seconds() <= 0.4 {
        let seq = heartbeat_seq
        heartbeat_seq = heartbeat_seq + 1
        let now = ctx.clock.now_seconds()
        println(
          "[\{now}s] Leader(Node 1) 发送心跳包 #\{seq} -> Node 2, Node 3",
        )

        let _ = topo.send_packet(1, 2, "HEARTBEAT #\{seq}", 5, fn(pkt) {
          println("[\{sim.now()}s] Follower(Node 2) 收到: \{pkt.payload}")
        })
        let _ = topo.send_packet(1, 3, "HEARTBEAT #\{seq}", 5, fn(pkt) {
          println("[\{sim.now()}s] Follower(Node 3) 收到: \{pkt.payload}")
        })
        Some(0.05) // Send heartbeat every 50ms
      } else {
        None
      }
    },
  ]

  let leader_proc = sim.register_process("LeaderHeartbeat", steps)
  let _ = sim.start_process(leader_proc, 0.0, 5)

  // Inject Network Partition at t=0.12s (Node 3 goes Offline)
  let _ = sim.schedule(0.12, 0, fn() {
    println(
      "\n[!!! 故障注入 !!!] [\{sim.now()}s] Node 3 发生网络分区/宕机状态切换为 Offline\n",
    )
    topo.set_node_status(3, @network.Offline)
  })

  // Recover Node 3 at t=0.28s
  let _ = sim.schedule(0.28, 0, fn() {
    println(
      "\n[+++ 故障恢复 +++] [\{sim.now()}s] Node 3 网络分区恢复,状态切换为 Online\n",
    )
    topo.set_node_status(3, @network.Online)
  })

  sim.run_until(0.45)

  println("\n==================================================")
  println("               分布式网络通信统计                   ")
  println("==================================================")
  let link12 = topo.get_link(1, 2).unwrap()
  println("Link 1->2 (Leader -> Follower A):")
  println("  发送总数据包: \{link12.packets_sent()}")
  println("  成功送达: \{link12.packets_delivered()}")
  println("  丢失/超时: \{link12.packets_dropped()}")

  let link13 = topo.get_link(1, 3).unwrap()
  println("Link 1->3 (Leader -> Follower B [分区经历者]):")
  println("  发送总数据包: \{link13.packets_sent()}")
  println("  成功送达: \{link13.packets_delivered()}")
  println("  丢失/超时: \{link13.packets_dropped()}")
  println("==================================================\n")
}