///|
fn keys(count : Int) -> Array[String] {
  let result : Array[String] = []
  for index = 0; index < count; index = index + 1 {
    result.push("customer-\{index}")
  }
  result
}

///|
fn base_nodes() -> Array[@shard.ShardNode] {
  [
    @shard.ShardNode::new("store-a", zone="east", rack="rack-1"),
    @shard.ShardNode::new("store-b", zone="west", rack="rack-1"),
    @shard.ShardNode::new("store-c", zone="south", rack="rack-2"),
  ]
}

///|
fn show_node(value : String?) -> String {
  match value {
    Some(id) => id
    None => ""
  }
}

///|
fn main {
  let cluster = base_nodes()
  let placement = @shard.place_replicas(cluster, "customer-42", 3)
  println("placement=" + placement.to_json())

  let ring = @shard.ConsistentHashRing::build(cluster)
  println("ring_points=\{ring.point_count()}")
  println("ring_owner=\{show_node(ring.owner("customer-42"))}")
  println(
    "rendezvous_owner=\{show_node(@shard.rendezvous_owner(cluster, "customer-42"))}",
  )

  let workload = keys(1000)
  let distribution = @shard.analyze_distribution(workload, cluster, replicas=3)
  println("distribution=" + distribution.to_json())

  let expanded = base_nodes()
  expanded.push(@shard.ShardNode::new("store-d", zone="north", rack="rack-3"))
  let migration = @shard.plan_migration(workload, cluster, expanded, replicas=3)
  println(
    "migration_summary={\"keys\":\{migration.keys},\"moved_keys\":\{migration.moved_keys},\"ratio\":\{@shard.movement_ratio(migration)}}",
  )
  for index = 0
      index < migration.moves.length() && index < 5
      index = index + 1 {
    let item = migration.moves[index]
    println(
      "move=\{item.key}:\{@shard.move_kind_name(item.kind)}:\{show_node(item.from_node)}->\{show_node(item.to_node)}",
    )
  }
  let workflow = @shard.plan_safe_migration(
    workload,
    cluster,
    expanded,
    replicas=3,
    max_actions_per_wave=32,
    max_actions_per_node=4,
  )
  println(
    "safe_workflow={\"migrating_keys\":\{workflow.migrating_keys},\"actions\":\{workflow.actions.length()},\"waves\":\{workflow.waves.length()},\"blocked\":\{workflow.blocked_keys.length()},\"issues\":\{@shard.validate_safe_migration(workflow).length()}}",
  )
}