/*
 *  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.
 */

#ifndef MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_
#define MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_

#include <stddef.h>
#include <stdint.h>

#include <list>
#include <map>
#include <memory>
#include <queue>
#include <set>

#include "absl/types/optional.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

class RoundRobinPacketQueue {
 public:
  explicit RoundRobinPacketQueue(int64_t start_time_us);
  ~RoundRobinPacketQueue();

  struct QueuedPacket {
   public:
    QueuedPacket(
        int priority,
        RtpPacketToSend::Type type,
        uint32_t ssrc,
        uint16_t seq_number,
        int64_t capture_time_ms,
        int64_t enqueue_time_ms,
        size_t length_in_bytes,
        bool retransmission,
        uint64_t enqueue_order,
        std::multiset<int64_t>::iterator enqueue_time_it,
        absl::optional<std::list<std::unique_ptr<RtpPacketToSend>>::iterator>
            packet_it);
    QueuedPacket(const QueuedPacket& rhs);
    ~QueuedPacket();

    bool operator<(const QueuedPacket& other) const;

    int priority() const { return priority_; }
    RtpPacketToSend::Type type() const { return type_; }
    uint32_t ssrc() const { return ssrc_; }
    uint16_t sequence_number() const { return sequence_number_; }
    int64_t capture_time_ms() const { return capture_time_ms_; }
    int64_t enqueue_time_ms() const { return enqueue_time_ms_; }
    size_t size_in_bytes() const { return bytes_; }
    bool is_retransmission() const { return retransmission_; }
    uint64_t enqueue_order() const { return enqueue_order_; }
    std::unique_ptr<RtpPacketToSend> ReleasePacket();

    // For internal use.
    absl::optional<std::list<std::unique_ptr<RtpPacketToSend>>::iterator>
    PacketIterator() const {
      return packet_it_;
    }
    std::multiset<int64_t>::iterator EnqueueTimeIterator() const {
      return enqueue_time_it_;
    }
    void SubtractPauseTimeMs(int64_t pause_time_sum_ms);

   private:
    RtpPacketToSend::Type type_;
    int priority_;
    uint32_t ssrc_;
    uint16_t sequence_number_;
    int64_t capture_time_ms_;  // Absolute time of frame capture.
    int64_t enqueue_time_ms_;  // Absolute time of pacer queue entry.
    size_t bytes_;
    bool retransmission_;
    uint64_t enqueue_order_;
    std::multiset<int64_t>::iterator enqueue_time_it_;
    // Iterator into |rtp_packets_| where the memory for RtpPacket is owned,
    // if applicable.
    absl::optional<std::list<std::unique_ptr<RtpPacketToSend>>::iterator>
        packet_it_;
  };

  void Push(int priority,
            RtpPacketToSend::Type type,
            uint32_t ssrc,
            uint16_t seq_number,
            int64_t capture_time_ms,
            int64_t enqueue_time_ms,
            size_t length_in_bytes,
            bool retransmission,
            uint64_t enqueue_order);
  void Push(int priority,
            int64_t enqueue_time_ms,
            uint64_t enqueue_order,
            std::unique_ptr<RtpPacketToSend> packet);
  QueuedPacket* BeginPop();
  void CancelPop();
  void FinalizePop();

  bool Empty() const;
  size_t SizeInPackets() const;
  uint64_t SizeInBytes() const;

  int64_t OldestEnqueueTimeMs() const;
  int64_t AverageQueueTimeMs() const;
  void UpdateQueueTime(int64_t timestamp_ms);
  void SetPauseState(bool paused, int64_t timestamp_ms);

 private:
  struct StreamPrioKey {
    StreamPrioKey(int priority, int64_t bytes)
        : priority(priority), bytes(bytes) {}

    bool operator<(const StreamPrioKey& other) const {
      if (priority != other.priority)
        return priority < other.priority;
      return bytes < other.bytes;
    }

    const int priority;
    const size_t bytes;
  };

  struct Stream {
    Stream();
    Stream(const Stream&);

    virtual ~Stream();

    size_t bytes;
    uint32_t ssrc;
    std::priority_queue<QueuedPacket> packet_queue;

    // Whenever a packet is inserted for this stream we check if |priority_it|
    // points to an element in |stream_priorities_|, and if it does it means
    // this stream has already been scheduled, and if the scheduled priority is
    // lower than the priority of the incoming packet we reschedule this stream
    // with the higher priority.
    std::multimap<StreamPrioKey, uint32_t>::iterator priority_it;
  };

  static constexpr size_t kMaxLeadingBytes = 1400;

  void Push(QueuedPacket packet);

  Stream* GetHighestPriorityStream();

  // Just used to verify correctness.
  bool IsSsrcScheduled(uint32_t ssrc) const;

  int64_t time_last_updated_ms_;
  absl::optional<QueuedPacket> pop_packet_;
  absl::optional<Stream*> pop_stream_;

  bool paused_ = false;
  size_t size_packets_ = 0;
  size_t size_bytes_ = 0;
  size_t max_bytes_ = kMaxLeadingBytes;
  int64_t queue_time_sum_ms_ = 0;
  int64_t pause_time_sum_ms_ = 0;

  // A map of streams used to prioritize from which stream to send next. We use
  // a multimap instead of a priority_queue since the priority of a stream can
  // change as a new packet is inserted, and a multimap allows us to remove and
  // then reinsert a StreamPrioKey if the priority has increased.
  std::multimap<StreamPrioKey, uint32_t> stream_priorities_;

  // A map of SSRCs to Streams.
  std::map<uint32_t, Stream> streams_;

  // The enqueue time of every packet currently in the queue. Used to figure out
  // the age of the oldest packet in the queue.
  std::multiset<int64_t> enqueue_times_;

  // List of RTP packets to be sent, not necessarily in the order they will be
  // sent. PacketInfo.packet_it will point to an entry in this list, or the
  // end iterator of this list if queue does not have direct ownership of the
  // packet.
  std::list<std::unique_ptr<RtpPacketToSend>> rtp_packets_;
};
}  // namespace webrtc

#endif  // MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_
