///|
fn main {
  let payload = @note.demo_payload()
  let cards = @note.weave("moonbit-demo", payload, 3)
  println("MoonBit Shard Note")
  println("purpose: printable short-message cards with resilient recovery")
  println("")
  println("legacy SN1 demo")
  println(@note.render_sheet(cards))
  println("")
  println("simulate: card 1 is missing, parity card is still available")
  let partial = [cards[0], cards[2], cards[3]]
  match @note.recover(partial) {
    @note.Restored(restored) =>
      println("recover: ok, payload cells = " + render_ints(restored))
    @note.NeedCards(missing) =>
      println("recover: need cards " + render_ints(missing))
    @note.Damaged(message) => println("recover: damaged deck: " + message)
  }
  println("")
  println("resilient RSN1 demo")
  let robust_payload = @note.ascii_payload("MoonBit resilient shard notes")
  let robust_cards = @note.weave_resilient(
    "moonbit-rs-demo", robust_payload, 6, 3,
  )
  let partial = @note.drop_resilient_indices(robust_cards, [1, 4])
  println(@note.resilient_capacity_summary(partial))
  match @note.recover_resilient(partial) {
    @note.ResilientRestored(restored) => {
      println("recover-rs: ok, text = " + @note.payload_to_ascii(restored))
      println("payload: " + @note.render_payload_profile(restored))
    }
    @note.ResilientNeedCards(missing) =>
      println("recover-rs: need cards " + render_ints(missing))
    @note.ResilientDamaged(message) =>
      println("recover-rs: damaged deck: " + message)
  }
  println("")
  println(
    "copy estimate: " +
    @note.render_copy_estimate(@note.estimate_copy_work(robust_cards)),
  )
  println(
    "scenario catalog: " +
    @note.count_passing_builtin_scenarios().to_string() +
    "/120 passed",
  )
}

///|
fn render_ints(values : Array[Int]) -> String {
  let parts : Array[String] = []
  for value in values {
    parts.push(value.to_string())
  }
  "[" + parts.join(", ") + "]"
}