/*
 *  Copyright (c) 2017 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.
 */

#include "modules/pacing/packet_queue.h"

#include <algorithm>
#include <list>
#include <vector>

#include "modules/include/module_common_types.h"
#include "modules/pacing/alr_detector.h"
#include "modules/pacing/bitrate_prober.h"
#include "modules/pacing/interval_budget.h"
#include "modules/utility/include/process_thread.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/field_trial.h"

namespace webrtc {

PacketQueue::PacketQueue(const Clock* clock)
    : bytes_(0),
      clock_(clock),
      queue_time_sum_(0),
      time_last_updated_(clock_->TimeInMilliseconds()),
      paused_(false) {}

PacketQueue::~PacketQueue() {}

void PacketQueue::Push(const Packet& packet) {
  UpdateQueueTime(packet.enqueue_time_ms);

  // Store packet in list, use pointers in priority queue for cheaper moves.
  // Packets have a handle to its own iterator in the list, for easy removal
  // when popping from queue.
  packet_list_.push_front(packet);
  std::list<Packet>::iterator it = packet_list_.begin();
  it->this_it = it;          // Handle for direct removal from list.
  prio_queue_.push(&(*it));  // Pointer into list.
  bytes_ += packet.bytes;
}

const PacketQueueInterface::Packet& PacketQueue::BeginPop() {
  const Packet& packet = *prio_queue_.top();
  prio_queue_.pop();
  return packet;
}

void PacketQueue::CancelPop(const Packet& packet) {
  prio_queue_.push(&(*packet.this_it));
}

void PacketQueue::FinalizePop(const Packet& packet) {
  bytes_ -= packet.bytes;
  int64_t packet_queue_time_ms = time_last_updated_ - packet.enqueue_time_ms;
  RTC_DCHECK_LE(packet.sum_paused_ms, packet_queue_time_ms);
  packet_queue_time_ms -= packet.sum_paused_ms;
  RTC_DCHECK_LE(packet_queue_time_ms, queue_time_sum_);
  queue_time_sum_ -= packet_queue_time_ms;
  packet_list_.erase(packet.this_it);
  RTC_DCHECK_EQ(packet_list_.size(), prio_queue_.size());
  if (packet_list_.empty())
    RTC_DCHECK_EQ(0, queue_time_sum_);
}

bool PacketQueue::Empty() const {
  return prio_queue_.empty();
}

size_t PacketQueue::SizeInPackets() const {
  return prio_queue_.size();
}

uint64_t PacketQueue::SizeInBytes() const {
  return bytes_;
}

int64_t PacketQueue::OldestEnqueueTimeMs() const {
  auto it = packet_list_.rbegin();
  if (it == packet_list_.rend())
    return 0;
  return it->enqueue_time_ms;
}

void PacketQueue::UpdateQueueTime(int64_t timestamp_ms) {
  RTC_DCHECK_GE(timestamp_ms, time_last_updated_);
  if (timestamp_ms == time_last_updated_)
    return;

  int64_t delta_ms = timestamp_ms - time_last_updated_;

  if (paused_) {
    // Increase per-packet accumulators of time spent in queue while paused,
    // so that we can disregard that when subtracting main accumulator when
    // popping packet from the queue.
    for (auto& it : packet_list_) {
      it.sum_paused_ms += delta_ms;
    }
  } else {
    // Use packet packet_list_.size() not prio_queue_.size() here, as there
    // might be an outstanding element popped from prio_queue_ currently in
    // the SendPacket() call, while packet_list_ will always be correct.
    queue_time_sum_ += delta_ms * packet_list_.size();
  }
  time_last_updated_ = timestamp_ms;
}

void PacketQueue::SetPauseState(bool paused, int64_t timestamp_ms) {
  if (paused_ == paused)
    return;
  UpdateQueueTime(timestamp_ms);
  paused_ = paused;
}

int64_t PacketQueue::AverageQueueTimeMs() const {
  if (prio_queue_.empty())
    return 0;
  return queue_time_sum_ / packet_list_.size();
}

}  // namespace webrtc
