/*
 *  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 "absl/base/attributes.h"
#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();

  ABSL_MUST_USE_RESULT InsertResult
  InsertPacket(std::unique_ptr<Packet> packet);
  ABSL_MUST_USE_RESULT 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_
