///|
/// 范围 WAL 中的一帧;byte_offset 使用 Int64,指向帧头,其他字段保持原帧语义。
pub(all) struct RangeWalFrame {
  index : Int
  byte_offset : Int64
  page_number : UInt
  database_pages : UInt
  checksum1 : UInt
  checksum2 : UInt
} derive(Debug, Eq)

///|
pub extend RangeWalFrame with @debug.Debug::{to_repr}

///|
pub extend RangeWalFrame with Eq::{equal, not_equal}

///|
/// 范围 WAL 的有效提交边界;帧号仍为 Int,逻辑页数来自提交帧。
pub(all) struct RangeWalCommit {
  frame_index : Int
  database_pages : UInt
} derive(Debug, Eq)

///|
pub extend RangeWalCommit with @debug.Debug::{to_repr}

///|
pub extend RangeWalCommit with Eq::{equal, not_equal}

///|
/// 范围 WAL 报告;stop_offset 与 trailing_bytes 为 Int64,未完成校验的帧不能用于最新快照。
pub(all) struct RangeWalInspection {
  header : WalHeader?
  frames : Array[RangeWalFrame]
  commits : Array[RangeWalCommit]
  committed_frames : Int
  database_pages : UInt?
  stop_reason : WalStopReason
  stop_offset : Int64
  trailing_bytes : Int64
} derive(Debug)

///|
pub extend RangeWalInspection with @debug.Debug::{to_repr}

///|
/// 只接受连续有效帧;遇到首个无效帧后不搜索更后面的提交标记。
/// 逐帧验证 64 位静态 WAL 源,不持有完整 WAL;默认帧预算 100000。实际宿主失败抛 source/ 错误,不作为有效前缀成功。
pub fn inspect_wal_source(
  source : &RangeSource,
  max_frames? : Int = 100000,
) -> RangeWalInspection raise SqliteError {
  let cursor = WalCursor::new(source.byte_length64(), max_frames~)
  while true {
    match cursor.next() {
      NeedWalRange(offset, count) =>
        cursor.provide(offset, range_sqlite_read(source, offset, count))
      WalReady(report) => return report
    }
  } nobreak {
    abort("WAL 游标未结束")
  }
}