///|
priv struct Meta {
  root : Int32
  freelist : Int32
  txn_id : Int32
  page_count : Int32
}

///|
fn blank_page() -> FixedArray[Byte] {
  FixedArray::make(page_size, b'\x00')
}

///|
fn page_bytes(page : FixedArray[Byte]) -> Bytes {
  fixed_to_bytes(page)
}

///|
/// 第 0 页:magic、version、page_size、root、freelist、txn_id、page_count、crc32
fn encode_header(meta : Meta) -> FixedArray[Byte] {
  let page = blank_page()
  copy_bytes(magic, page, 0)
  write_u32(page, 8, format_version)
  write_u32(page, 12, page_size.reinterpret_as_uint())
  write_u64_int(page, 16, meta.root)
  write_u64_int(page, 24, meta.freelist)
  write_u64_int(page, 32, meta.txn_id)
  write_u64_int(page, 40, meta.page_count)
  write_u32(
    page,
    header_len,
    crc32(page.unsafe_reinterpret_as_bytes()[:header_len]),
  )
  page
}

///|
fn decode_header(page : Bytes) -> Meta raise DbError {
  guard header_version(page) == format_version else { raise DbError::Corrupt }
  {
    root: read_u64_as_int(page, 16),
    freelist: read_u64_as_int(page, 24),
    txn_id: read_u64_as_int(page, 32),
    page_count: read_u64_as_int(page, 40),
  }
}