// stream.mbt
//
// 流式解码(M6 增量):不一次性物化整条流,逐块取样;`seek` 支持
// 按 SEEKTABLE 跳帧,没有 SEEKTABLE 时从流起点线性推进(正确优先,
// 以编号做头扫描的快速路径留作后续增量)。

///|
/// 按块流式读取的 FLAC 解码器。
pub struct FlacStream {
  /// 流的 STREAMINFO。
  info : StreamInfo
  br : BitReader
  blocks : Array[MetadataBlock]
  frame_offset : Int32
  /// 已消费(并已交给调用方)的样本位置。
  mut decoded : Int64
  /// seek 后待返回的目标块尾部(planar);空数组表示无。
  mut pending : Array[Array[Int32]]
  mut eof : Bool
}

///|
/// 解析元数据并就绪于第一个音频帧。
pub fn FlacStream::new(data : Bytes) -> FlacStream raise FlacError {
  let meta = parse_metadata(data)
  let br = BitReader::new(data)
  br.seek(meta.frame_offset * 8)
  {
    info: meta.stream_info,
    br,
    blocks: meta.blocks,
    frame_offset: meta.frame_offset,
    decoded: 0,
    pending: [],
    eof: false,
  }
}

///|
/// 回到流起点。
fn FlacStream::rewind(self : FlacStream) -> Unit {
  self.br.truncated = false
  self.br.seek(self.frame_offset * 8)
  self.decoded = 0
  self.pending = []
}

///|
/// 取下一块样本(planar,`[声道][样本]`)。返回 `None` 表示流已结束。
/// `total_samples` 已知且不足时抛 Truncated,与 `decode` 口径一致。
pub fn FlacStream::next(
  self : FlacStream,
) -> Array[Array[Int32]]? raise FlacError {
  if self.pending.length() > 0 {
    let p = self.pending
    self.pending = []
    return Some(p)
  }
  if self.eof {
    return None
  }
  let total = self.info.total_samples
  if total > 0 && self.decoded >= total {
    self.eof = true
    return None
  }
  match decode_next_block(self.br, self.info) {
    None => {
      self.eof = true
      if total > 0 && self.decoded < total {
        raise Truncated(
          offset=self.br.data.length(),
          need=(total - self.decoded).to_int(),
          actual=self.decoded.to_int(),
        )
      }
      None
    }
    Some(b) => {
      let take64 = if total > 0 &&
        self.decoded + Int64::from_int(b.block_size) > total {
        total - self.decoded
      } else {
        Int64::from_int(b.block_size)
      }
      let take = take64.to_int()
      let out : Array[Array[Int32]] = []
      for c in 0.. Unit raise FlacError {
  self.pending = []
  self.eof = false
  let total = self.info.total_samples
  if sample <= 0 {
    self.rewind()
    return
  }
  if total > 0 && sample >= total {
    // 跳到流尾:样本位置推进到总长,下一次 next 返回 None
    self.rewind()
    self.decoded = total
    return
  }
  // —— SEEKTABLE:取样本号不大于 sample 的最后一个点 ——
  let mut best_byte : Int64 = -1
  let mut best_sample : Int64 = -1
  for blk in self.blocks {
    if blk.block_type == 3 {
      let pts = read_seektable(self.br.data, blk)
      for p in pts {
        if p.sample_position <= sample && p.sample_position > best_sample {
          best_sample = p.sample_position
          best_byte = p.byte_offset
        }
      }
    }
  }
  if best_byte >= 0 {
    let start_bit = (best_byte * 8).to_int()
    self.br.truncated = false
    self.br.seek(start_bit)
    // 试探:该偏移必须能解析出帧头,否则视为点表不可信,回退线性
    let probe : FrameHeader? = {
      let saved = self.br.pos
      let h = try_parse_header(self.br, self.info)
      self.br.truncated = false
      self.br.seek(saved)
      h
    }
    if probe is Some(_) {
      self.decoded = best_sample
    } else {
      self.rewind()
    }
  } else {
    self.rewind()
  }
  // —— 线性推进到包含 sample 的块,裁出尾部作 pending ——
  while !self.eof {
    let cur = self.decoded
    match decode_next_block(self.br, self.info) {
      None => self.eof = true
      Some(b) => {
        let take64 = if total > 0 && cur + Int64::from_int(b.block_size) > total {
          total - cur
        } else {
          Int64::from_int(b.block_size)
        }
        self.decoded = cur + take64
        if sample < cur + Int64::from_int(b.block_size) {
          // 目标落在本块内
          let off = (sample - cur).to_int()
          let take = take64.to_int()
          let pend : Array[Array[Int32]] = []
          for c in 0..