/*
 *  Copyright (c) 2016 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_VIDEO_CODING_PACKET_BUFFER_H_
#define MODULES_VIDEO_CODING_PACKET_BUFFER_H_

#include <bit>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <set>
#include <vector>

#include "api/rtp_packet_info.h"
#include "api/video/video_codec_type.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
#include "rtc_base/checks.h"
#include "rtc_base/copy_on_write_buffer.h"

namespace webrtc {
namespace video_coding {

class PacketBuffer {
 public:
  struct Packet {
    Packet() = default;
    Packet(const RtpPacketReceived& rtp_packet,
           int64_t sequence_number,
           const RTPVideoHeader& video_header);
    Packet(const Packet&) = delete;
    Packet(Packet&&) = delete;
    Packet& operator=(const Packet&) = delete;
    Packet& operator=(Packet&&) = delete;
    ~Packet() = default;

    VideoCodecType codec() const { return video_header.codec; }
    int width() const { return video_header.width; }
    int height() const { return video_header.height; }

    bool is_first_packet_in_frame() const {
      return video_header.is_first_packet_in_frame;
    }
    bool is_last_packet_in_frame() const {
      return video_header.is_last_packet_in_frame;
    }
    int64_t seq_num() const { return sequence_number; }

    // If all its previous packets have been inserted into the packet buffer.
    // Set and used internally by the PacketBuffer.
    bool continuous = false;
    bool marker_bit = false;
    uint8_t payload_type = 0;
    int64_t sequence_number = 0;
    uint32_t timestamp = 0;
    int times_nacked = -1;

    CopyOnWriteBuffer video_payload;
    RTPVideoHeader video_header;
    RtpPacketInfo rtp_packet_info;
  };
  struct InsertResult {
    std::vector<std::unique_ptr<Packet>> packets;
    // Indicates if the packet buffer was cleared, which means that a key
    // frame request should be sent.
    bool buffer_cleared = false;
  };

  // Both `start_buffer_size` and `max_buffer_size` must be a power of 2.
  PacketBuffer(size_t start_buffer_size, size_t max_buffer_size);
  ~PacketBuffer();

  [[nodiscard]] InsertResult InsertPacket(std::unique_ptr<Packet> packet);
  [[nodiscard]] InsertResult InsertPadding(int64_t seq_num);
  void ClearTo(int64_t seq_num);
  void Clear();

  void ForceSpsPpsIdrIsH264Keyframe();
  void ResetSpsPpsIdrIsH264Keyframe();

 private:
  void ClearInternal();

  // Tries to expand the buffer.
  bool ExpandBufferSize();

  // Test if all previous packets has arrived for the given sequence number.
  bool PotentialNewFrame(int64_t seq_num) const;

  // Test if all packets of a frame has arrived, and if so, returns packets to
  // create frames.
  std::vector<std::unique_ptr<Packet>> FindFrames(int64_t seq_num);

  void UpdateMissingPackets(int64_t seq_num);

  static size_t Index(int64_t seq_num, size_t buffer_size) {
    RTC_DCHECK(std::has_single_bit(buffer_size));
    size_t mask = buffer_size - 1;
    return seq_num & mask;
  }

  size_t Index(int64_t seq_num) const { return Index(seq_num, buffer_.size()); }

  // buffer_.size() and max_size_ must always be a power of two.
  const size_t max_size_;

  // The fist sequence number currently in the buffer.
  int64_t first_seq_num_;

  // If the packet buffer has received its first packet.
  bool first_packet_received_;

  // If the buffer is cleared to `first_seq_num_`.
  bool is_cleared_to_first_seq_num_;

  // Buffer that holds the the inserted packets and information needed to
  // determine continuity between them.
  std::vector<std::unique_ptr<Packet>> buffer_;

  std::optional<int64_t> newest_inserted_seq_num_;
  std::set<int64_t> missing_packets_;
  std::set<int64_t> received_padding_;

  // Indicates if we should require SPS, PPS, and IDR for a particular
  // RTP timestamp to treat the corresponding frame as a keyframe.
  bool sps_pps_idr_is_h264_keyframe_;
};

}  // namespace video_coding
}  // namespace webrtc

#endif  // MODULES_VIDEO_CODING_PACKET_BUFFER_H_
