// 环形队列 线程安全
template <typename T>
class CircularQueue {
 private:
  std::vector<T> data;
  int head;
  int tail;
  int size;
  int count;
  std::mutex mtx;

 public:
  CircularQueue() {
    head = -1;
    tail = -1;
    size = 0;
    count = 0;
  }
  CircularQueue(int k) {
    data.resize(k);
    head = -1;
    tail = -1;
    size = k;
    count = 0;
  }
  void resize(int k) {
    std::lock_guard<std::mutex> lock(mtx);
    data.resize(k);
    size = k;
  }
  bool push(const T& value) {
    std::lock_guard<std::mutex> lock(mtx);
    if (isFull()) {
      pop();
    }
    if (isEmpty()) {
      head = 0;
    }
    tail = (tail + 1) % size;
    data[tail] = value;
    count++;
    return true;
  }
  void print() {
    std::lock_guard<std::mutex> lock(mtx);
    if (isEmpty()) {
      std::cout << "Queue is empty." << std::endl;
      return;
    }
    int i = head;
    std::cout << "Queue: ";
    while (i != tail) {
      std::cout << data[i] << " ";
      i = (i + 1) % size;
    }
    std::cout << data[tail] << std::endl;
  }

  T get(int index) {
    std::lock_guard<std::mutex> lock(mtx);
    if (isEmpty() || index < 0 || index >= count) {
      return T();
    }
    return data[(head + index) % size];
  }

  size_t getCount() {
    std::lock_guard<std::mutex> lock(mtx);
    return count;
  }

  T front() {
    std::lock_guard<std::mutex> lock(mtx);
    if (isEmpty()) {
      return T();
    }
    return data[head];
  }

  T rear() {
    std::lock_guard<std::mutex> lock(mtx);
    if (isEmpty()) {
      return T();
    }
    return data[tail];
  }

 private:
  // 这几个在内部调用 不重复加锁
  bool pop() {
    if (isEmpty()) {
      return false;
    }
    if (head == tail) {
      head = -1;
      tail = -1;
      count = 0;
      return true;
    }
    head = (head + 1) % size;
    count--;
    return true;
  }

  bool isEmpty() { return head == -1; }

  bool isFull() { return count == size; }
};