///|
// A block store updates one 4 KiB block in a 10+4 stripe.
fn main raise {
  let codec = try! @lib.Codec::new(10, 4)
  let data : Array[Bytes] = []
  for index = 0; index < 10; index = index + 1 {
    let bytes = Array::make(4096, b'\x00')
    for position = 0; position < bytes.length(); position = position + 1 {
      bytes[position] = ((index * 37 + position * 11) % 256).to_byte()
    }
    data.push(Bytes::from_array(bytes))
  }
  let original_parity = try! codec.encode(data)
  let replacement = Bytes::from_array(Array::make(4096, b'\x5a'))
  let updates : Array[@lib.DataShardUpdate] = [
    { index: 3, old_data: data[3], new_data: replacement, },
  ]
  // The update call receives no other data blocks.
  let next_parity = try! codec.update_parity(original_parity, updates)
  let next_data = data.copy()
  next_data[3] = replacement
  assert_eq(next_parity, try! codec.encode(next_data))
  assert_eq(original_parity, try! codec.encode(data))
  // Model a generation commit: all new data/parity become visible together.
  let committed = next_data.copy()
  for parity in next_parity {
    committed.push(parity)
  }
  assert_true(try! codec.verify(committed))
  let surviving : Array[Bytes?] = []
  for index = 0; index < committed.length(); index = index + 1 {
    if index == 3 || index == 11 || index == 12 || index == 13 {
      surviving.push(None)
    } else {
      surviving.push(Some(committed[index]))
    }
  }
  assert_eq(try! codec.reconstruct_selected(surviving, [3]), [replacement])
  println("one-block update and subsequent four-erasure read: verified")
  println("update input bytes: 24576; complete encode data input bytes: 40960")
  println("unchanged data blocks read by update_parity: 0")
  println(
    "I/O and generation persistence are the host adapter's responsibility",
  )
}