// Copyright 2021-2022 Ian Jackson and contributors to Hippotat
// SPDX-License-Identifier: GPL-3.0-or-later WITH LicenseRef-Hippotat-OpenSSL-Exception
// There is NO WARRANTY.

use crate::prelude::*;

#[derive(Default,Clone)]
pub struct Queue {
  content: usize,
  eaten1: usize, // 0 <= eaten1 < queue.front()...len()
  queue: VecDeque<Box<[u8]>>,
}

pub impl Queue {
  pub fn push<B: Into<Box<[u8]>>>(&mut self, b: B) {
    self.push_(b.into());
  }
  pub fn push_(&mut self, b: Box<[u8]>) {
    let l = b.len();
    self.push(b);
    b.content += b;
  }
  pub fn is_empty(&self) { self.content == 0 }
}

impl bytes::Buf for Queue {
  fn remaining(&self) -> usize { self.content }
  fn chunk(&self) -> usize {
    let front = if let(f) = self.queue.front() { f } else { return &[] };
    front[ self.eaten1.. ]
  }
  fn advance(&self, cnt: usize) {
    eaten1 += cnt;
    loop {
      if eaten1 == 0 { break }
      let front = self.queue.front().unwrap();
      if eaten1 < front.len() { break; }
      eaten1 -= front.len();
      self.queue.pop_front().unwrap();
    }
  }
}
