///|
/// 有界二进制读取器。内部持有 `BytesView`,子区域解析不会复制底层字节。
pub struct Decoder {
  input : BytesView
  base_offset : Int
  mut offset : Int
  mut bit_offset : Int
  mut field_path : String
  depth : Int
  limits : Limits
  trace_entries : Array[TraceEntry]
}

///|
pub fn Decoder::new(input : Bytes, limits : Limits) -> Decoder {
  Decoder::new_view(input[:], limits)
}

///|
/// 从借用视图创建 Decoder,适合解析大缓冲区中的子区间而不复制。
pub fn Decoder::new_view(input : BytesView, limits : Limits) -> Decoder {
  {
    input,
    base_offset: 0,
    offset: 0,
    bit_offset: 0,
    field_path: "",
    depth: 0,
    limits,
    trace_entries: [],
  }
}

///|
pub fn Decoder::offset(self : Decoder) -> Int {
  self.offset
}

///|
pub fn Decoder::absolute_offset(self : Decoder) -> Int {
  self.base_offset + self.offset
}

///|
pub fn Decoder::remaining(self : Decoder) -> Int {
  self.input.length() - self.offset
}

///|
pub fn Decoder::total_length(self : Decoder) -> Int {
  self.input.length()
}

///|
pub fn Decoder::path(self : Decoder) -> String {
  self.field_path
}

///|
pub fn Decoder::trace(self : Decoder) -> Array[TraceEntry] {
  self.trace_entries.copy()
}

///|
pub fn Decoder::max_collection_length(self : Decoder) -> Int {
  self.limits.max_collection_length
}

///|
pub fn Decoder::max_depth(self : Decoder) -> Int {
  self.limits.max_depth
}

///|
/// 借用当前 Decoder 区域内任意绝对相对偏移的字节,不移动游标。
/// offset 相对于当前 Decoder 区域起点,而不是当前 cursor。
pub fn Decoder::view_at(
  self : Decoder,
  offset : Int,
  count : Int,
) -> Result[BytesView, BinError] {
  if offset < 0 || count < 0 {
    return Err(
      BinError::new(
        InvalidValue,
        self.absolute_offset(),
        self.field_path,
        "random-access offset and count must be non-negative",
      ),
    )
  }
  if offset > self.input.length() || count > self.input.length() - offset {
    return Err(
      BinError::new(
        UnexpectedEof,
        self.base_offset + offset,
        self.field_path,
        "random-access byte range exceeds decoder bounds",
      ),
    )
  }
  Ok(self.input[offset:offset + count])
}

///|
fn Decoder::consumed_bytes(self : Decoder) -> Int {
  self.offset + (if self.bit_offset == 0 { 0 } else { 1 })
}

///|
fn Decoder::trace_end_offset(self : Decoder) -> Int {
  self.base_offset + self.consumed_bytes()
}

///|
/// Finalize a byte-framed decode. Partial final bytes are accepted only when
/// the unread low bits are zero, matching Encoder::finish zero padding.
fn Decoder::finish_decode(
  self : Decoder,
  require_eof : Bool,
) -> Result[Int, BinError] {
  let consumed = self.consumed_bytes()
  if self.bit_offset != 0 {
    let unread = 8 - self.bit_offset
    let mask = (1U << unread) - 1U
    if (self.input[self.offset].to_uint() & mask) != 0U {
      return Err(
        BinError::new(
          InvalidValue,
          self.trace_end_offset() - 1,
          self.field_path,
          "non-zero padding bits after decoded value",
        ),
      )
    }
  }
  if require_eof && consumed != self.input.length() {
    Err(
      BinError::new(
        TrailingBytes,
        self.base_offset + consumed,
        self.field_path,
        "trailing bytes after decoded value",
      ),
    )
  } else {
    Ok(consumed)
  }
}

///|
pub fn Decoder::depth(self : Decoder) -> Int {
  self.depth
}

///|
fn Decoder::new_child(
  input : BytesView,
  base_offset : Int,
  path : String,
  depth : Int,
  limits : Limits,
) -> Decoder {
  {
    input,
    base_offset,
    offset: 0,
    bit_offset: 0,
    field_path: path,
    depth,
    limits,
    trace_entries: [],
  }
}

///|
fn Decoder::error(
  self : Decoder,
  kind : ErrorKind,
  message : String,
) -> BinError {
  BinError::new(kind, self.absolute_offset(), self.field_path, message)
}

///|
fn Decoder::ensure_byte_aligned(self : Decoder) -> Result[Unit, BinError] {
  if self.bit_offset == 0 {
    Ok(())
  } else {
    Err(self.error(Misaligned, "operation requires byte alignment"))
  }
}

///|
/// 借用接下来 `count` 个字节,不复制底层缓冲区。
pub fn Decoder::take_view(
  self : Decoder,
  count : Int,
) -> Result[BytesView, BinError] {
  match self.ensure_byte_aligned() {
    Err(error) => Err(error)
    Ok(_) =>
      if count < 0 {
        Err(self.error(InvalidValue, "byte count cannot be negative"))
      } else if count > self.remaining() {
        Err(self.error(UnexpectedEof, "not enough bytes for requested field"))
      } else {
        let start = self.offset
        self.offset = self.offset + count
        Ok(self.input[start:self.offset])
      }
  }
}

///|
/// 读取拥有所有权的字节串。需要零拷贝时优先使用 `take_view`。
pub fn Decoder::take_bytes(
  self : Decoder,
  count : Int,
) -> Result[Bytes, BinError] {
  match self.take_view(count) {
    Err(error) => Err(error)
    Ok(view) => Ok(view.to_owned())
  }
}

///|
/// 读取单个字节,避免为整数/变长整数解析创建临时字节串。
pub fn Decoder::read_byte(self : Decoder) -> Result[Byte, BinError] {
  match self.take_view(1) {
    Err(error) => Err(error)
    Ok(view) => Ok(view[0])
  }
}

///|
pub fn Decoder::read_uint(
  self : Decoder,
  width : Int,
  endian : Endian,
) -> Result[UInt, BinError] {
  guard width == 1 || width == 2 || width == 4 else {
    return Err(self.error(Unsupported, "UInt width must be 1, 2, or 4"))
  }
  match self.take_view(width) {
    Err(error) => Err(error)
    Ok(bytes) => {
      let mut value = 0U
      match endian {
        Big =>
          for byte in bytes {
            value = (value << 8) | byte.to_uint()
          }
        Little =>
          for index, byte in bytes {
            value = value | (byte.to_uint() << (index * 8))
          }
      }
      Ok(value)
    }
  }
}

///|
pub fn Decoder::read_uint64(
  self : Decoder,
  endian : Endian,
) -> Result[UInt64, BinError] {
  match self.take_view(8) {
    Err(error) => Err(error)
    Ok(bytes) => {
      let mut value = 0UL
      match endian {
        Big =>
          for byte in bytes {
            value = (value << 8) | byte.to_uint64()
          }
        Little =>
          for index, byte in bytes {
            value = value | (byte.to_uint64() << (index * 8))
          }
      }
      Ok(value)
    }
  }
}

///|
pub fn Decoder::read_bits_msb(
  self : Decoder,
  width : Int,
) -> Result[UInt, BinError] {
  guard width > 0 && width <= 32 else {
    return Err(self.error(InvalidValue, "bit width must be in 1..32"))
  }
  let mut value = 0U
  for index = 0; index < width; index = index + 1 {
    if self.offset >= self.input.length() {
      return Err(
        self.error(UnexpectedEof, "not enough bits for requested field"),
      )
    }
    let byte = self.input[self.offset].to_uint()
    let shift = 7 - self.bit_offset
    value = (value << 1) | ((byte >> shift) & 1U)
    self.bit_offset = self.bit_offset + 1
    if self.bit_offset == 8 {
      self.bit_offset = 0
      self.offset = self.offset + 1
    }
  }
  Ok(value)
}

///|
pub fn Decoder::align_byte(self : Decoder) -> Unit {
  if self.bit_offset != 0 {
    self.bit_offset = 0
    self.offset = self.offset + 1
  }
}

///|
fn[T] Decoder::with_path(
  self : Decoder,
  name : String,
  action : () -> Result[T, BinError],
) -> Result[T, BinError] {
  let previous = self.field_path
  self.field_path = if previous == "" { name } else { previous + "." + name }
  let result = action()
  self.field_path = previous
  result
}

///|
fn Decoder::record(
  self : Decoder,
  path : String,
  kind : String,
  start : Int,
  end : Int,
  render_value : () -> String,
) -> Result[Unit, BinError] {
  if self.trace_entries.length() >= self.limits.max_trace_entries {
    Err(self.error(LimitExceeded, "trace entry limit exceeded"))
  } else {
    self.trace_entries.push({ path, kind, start, end, value: render_value(), })
    Ok(())
  }
}

///|
fn Decoder::append_trace(
  self : Decoder,
  entries : Array[TraceEntry],
) -> Result[Unit, BinError] {
  if entries.length() >
    self.limits.max_trace_entries - self.trace_entries.length() {
    return Err(self.error(LimitExceeded, "trace entry limit exceeded"))
  }
  for entry in entries {
    self.trace_entries.push(entry)
  }
  Ok(())
}