/*
 *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef TEST_PC_E2E_ANALYZER_VIDEO_MULTI_READER_QUEUE_H_
#define TEST_PC_E2E_ANALYZER_VIDEO_MULTI_READER_QUEUE_H_

#include <cstddef>
#include <deque>
#include <optional>
#include <set>
#include <unordered_map>

#include "rtc_base/checks.h"

namespace webrtc {

// Represents the queue which can be read by multiple readers. Each reader reads
// from its own queue head. When an element is added it will become visible for
// all readers. When an element will be removed by all the readers, the element
// will be removed from the queue.
template <typename T>
class MultiReaderQueue {
 public:
  // Creates queue with exactly `readers_count` readers named from 0 to
  // `readers_count - 1`.
  explicit MultiReaderQueue(size_t readers_count) {
    for (size_t i = 0; i < readers_count; ++i) {
      heads_[i] = 0;
    }
  }
  // Creates queue with specified readers.
  explicit MultiReaderQueue(std::set<size_t> readers) {
    for (size_t reader : readers) {
      heads_[reader] = 0;
    }
  }

  // Adds a new `reader`, initializing its reading position (the reader's head)
  // equal to the one of `reader_to_copy`.
  // Complexity O(MultiReaderQueue::size(reader_to_copy)).
  void AddReader(size_t reader, size_t reader_to_copy) {
    size_t pos = GetHeadPositionOrDie(reader_to_copy);

    auto it = heads_.find(reader);
    RTC_CHECK(it == heads_.end())
        << "Reader " << reader << " is already in the queue";
    heads_[reader] = heads_[reader_to_copy];
    for (size_t i = pos; i < queue_.size(); ++i) {
      in_queues_[i]++;
    }
  }

  // Adds a new `reader`, initializing its reading position equal to first
  // element in the queue.
  // Complexity O(MultiReaderQueue::size()).
  void AddReader(size_t reader) {
    auto it = heads_.find(reader);
    RTC_CHECK(it == heads_.end())
        << "Reader " << reader << " is already in the queue";
    heads_[reader] = removed_elements_count_;
    for (size_t i = 0; i < queue_.size(); ++i) {
      in_queues_[i]++;
    }
  }

  // Removes specified `reader` from the queue.
  // Complexity O(MultiReaderQueue::size(reader)).
  void RemoveReader(size_t reader) {
    size_t pos = GetHeadPositionOrDie(reader);
    for (size_t i = pos; i < queue_.size(); ++i) {
      in_queues_[i]--;
    }
    while (!in_queues_.empty() && in_queues_[0] == 0) {
      PopFront();
    }
    heads_.erase(reader);
  }

  // Add value to the end of the queue. Complexity O(1).
  void PushBack(T value) {
    queue_.push_back(value);
    in_queues_.push_back(heads_.size());
  }

  // Extract element from specified head. Complexity O(1).
  std::optional<T> PopFront(size_t reader) {
    size_t pos = GetHeadPositionOrDie(reader);
    if (pos >= queue_.size()) {
      return std::nullopt;
    }

    T out = queue_[pos];

    in_queues_[pos]--;
    heads_[reader]++;

    if (in_queues_[pos] == 0) {
      RTC_DCHECK_EQ(pos, 0);
      PopFront();
    }
    return out;
  }

  // Returns element at specified head. Complexity O(1).
  std::optional<T> Front(size_t reader) const {
    size_t pos = GetHeadPositionOrDie(reader);
    if (pos >= queue_.size()) {
      return std::nullopt;
    }
    return queue_[pos];
  }

  // Returns true if for specified head there are no more elements in the queue
  // or false otherwise. Complexity O(1).
  bool IsEmpty(size_t reader) const {
    size_t pos = GetHeadPositionOrDie(reader);
    return pos >= queue_.size();
  }

  // Returns size of the longest queue between all readers.
  // Complexity O(1).
  size_t size() const { return queue_.size(); }

  // Returns size of the specified queue. Complexity O(1).
  size_t size(size_t reader) const {
    size_t pos = GetHeadPositionOrDie(reader);
    return queue_.size() - pos;
  }

  // Complexity O(1).
  size_t readers_count() const { return heads_.size(); }

 private:
  size_t GetHeadPositionOrDie(size_t reader) const {
    auto it = heads_.find(reader);
    RTC_CHECK(it != heads_.end()) << "No queue for reader " << reader;
    return it->second - removed_elements_count_;
  }

  void PopFront() {
    RTC_DCHECK(!queue_.empty());
    RTC_DCHECK_EQ(in_queues_[0], 0);
    queue_.pop_front();
    in_queues_.pop_front();
    removed_elements_count_++;
  }

  // Number of the elements that were removed from the queue. It is used to
  // subtract from each head to compute the right index inside `queue_`;
  size_t removed_elements_count_ = 0;
  std::deque<T> queue_;
  // In how may queues the element at index `i` is. An element can be removed
  // from the front if and only if it is in 0 queues.
  std::deque<size_t> in_queues_;
  // Map from the reader to the head position in the queue.
  std::unordered_map<size_t, size_t> heads_;
};

}  // namespace webrtc

#endif  // TEST_PC_E2E_ANALYZER_VIDEO_MULTI_READER_QUEUE_H_
