/*
 *  Copyright (c) 2014 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/rtp_rtcp/source/rtcp_packet.h"

#include <cstddef>
#include <cstdint>
#include <span>

#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "rtc_base/buffer.h"
#include "rtc_base/checks.h"

namespace webrtc {
namespace rtcp {

Buffer RtcpPacket::Build() const {
  Buffer packet = Buffer::CreateWithCapacity(BlockLength());

  packet.AppendData(BlockLength(), [&](std::span<uint8_t> data) {
    size_t length = 0;
    bool created = Create(data.data(), &length, data.size(), nullptr);
    RTC_DCHECK(created) << "Invalid packet is not supported.";
    RTC_DCHECK_EQ(length, data.size())
        << "BlockLength mispredicted size used by Create";
    return length;
  });
  return packet;
}

bool RtcpPacket::Build(size_t max_length, PacketReadyCallback callback) const {
  RTC_CHECK_LE(max_length, IP_PACKET_SIZE);
  uint8_t buffer[IP_PACKET_SIZE];
  size_t index = 0;
  if (!Create(buffer, &index, max_length, callback))
    return false;
  return OnBufferFull(buffer, &index, callback);
}

bool RtcpPacket::OnBufferFull(uint8_t* packet,
                              size_t* index,
                              PacketReadyCallback callback) const {
  if (*index == 0)
    return false;
  RTC_DCHECK(callback) << "Fragmentation not supported.";
  callback(std::span<const uint8_t>(packet, *index));
  *index = 0;
  return true;
}

size_t RtcpPacket::HeaderLength() const {
  size_t length_in_bytes = BlockLength();
  RTC_DCHECK_GT(length_in_bytes, 0);
  RTC_DCHECK_EQ(length_in_bytes % 4, 0)
      << "Padding must be handled by each subclass.";
  // Length in 32-bit words without common header.
  return (length_in_bytes - kHeaderLength) / 4;
}

// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
//
// RTP header format.
//   0                   1                   2                   3
//   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |V=2|P| RC/FMT  |      PT       |             length            |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
void RtcpPacket::CreateHeader(
    size_t count_or_format,  // Depends on packet type.
    uint8_t packet_type,
    size_t length,
    uint8_t* buffer,
    size_t* pos) {
  CreateHeader(count_or_format, packet_type, length, /*padding=*/false, buffer,
               pos);
}

void RtcpPacket::CreateHeader(
    size_t count_or_format,  // Depends on packet type.
    uint8_t packet_type,
    size_t length,
    bool padding,
    uint8_t* buffer,
    size_t* pos) {
  RTC_DCHECK_LE(length, 0xffffU);
  RTC_DCHECK_LE(count_or_format, 0x1f);
  constexpr uint8_t kVersionBits = 2 << 6;
  uint8_t padding_bit = padding ? 1 << 5 : 0;
  buffer[*pos + 0] =
      kVersionBits | padding_bit | static_cast<uint8_t>(count_or_format);
  buffer[*pos + 1] = packet_type;
  buffer[*pos + 2] = (length >> 8) & 0xff;
  buffer[*pos + 3] = length & 0xff;
  *pos += kHeaderLength;
}

}  // namespace rtcp
}  // namespace webrtc
