/*
 *  Copyright (c) 2023 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/flexfec_header_reader_writer2.h"

#include <string.h>

#include "api/scoped_refptr.h"
#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {

namespace {

// Maximum number of media packets that can be protected in one batch.
constexpr size_t kMaxMediaPackets = 48;  // Since we are reusing ULPFEC masks.

// Maximum number of media packets tracked by FEC decoder.
// Maintain a sufficiently larger tracking window than `kMaxMediaPackets`
// to account for packet reordering in pacer/ network.
constexpr size_t kMaxTrackedMediaPackets = 4 * kMaxMediaPackets;

// Maximum number of FEC packets stored inside ForwardErrorCorrection.
constexpr size_t kMaxFecPackets = kMaxMediaPackets;

// Size (in bytes) of packet masks, given number of K bits set.
constexpr size_t kFlexfecPacketMaskSizes[] = {2, 6, 14};

// Size (in bytes) of part of header which is not packet mask specific.
constexpr size_t kBaseHeaderSize = 8;

// Size (in bytes) of part of header which is stream specific.
constexpr size_t kStreamSpecificHeaderSize = 2;

// Size (in bytes) of header, given the single stream packet mask size, i.e.
// the number of K-bits set.
constexpr size_t kHeaderSizes[] = {
    kBaseHeaderSize + kStreamSpecificHeaderSize + kFlexfecPacketMaskSizes[0],
    kBaseHeaderSize + kStreamSpecificHeaderSize + kFlexfecPacketMaskSizes[1],
    kBaseHeaderSize + kStreamSpecificHeaderSize + kFlexfecPacketMaskSizes[2]};

// We currently only support single-stream protection.
// TODO(brandtr): Update this when we support multistream protection.
constexpr uint8_t kSsrcCount = 1;

// There are three reserved bytes that MUST be set to zero in the header.
constexpr uint32_t kReservedBits = 0;

// TODO(brandtr): Update this when we support multistream protection.
constexpr size_t kPacketMaskOffset =
    kBaseHeaderSize + kStreamSpecificHeaderSize;

// Here we count the K-bits as belonging to the packet mask.
// This can be used in conjunction with FlexfecHeaderWriter::MinPacketMaskSize,
// which calculates a bound on the needed packet mask size including K-bits,
// given a packet mask without K-bits.
size_t FlexfecHeaderSize(size_t packet_mask_size) {
  RTC_DCHECK_LE(packet_mask_size, kFlexfecPacketMaskSizes[2]);
  if (packet_mask_size <= kFlexfecPacketMaskSizes[0]) {
    return kHeaderSizes[0];
  } else if (packet_mask_size <= kFlexfecPacketMaskSizes[1]) {
    return kHeaderSizes[1];
  }
  return kHeaderSizes[2];
}

}  // namespace

FlexfecHeaderReader2::FlexfecHeaderReader2()
    : FecHeaderReader(kMaxTrackedMediaPackets, kMaxFecPackets) {}

FlexfecHeaderReader2::~FlexfecHeaderReader2() = default;

// TODO(brandtr): Update this function when we support flexible masks,
// and retransmissions.
bool FlexfecHeaderReader2::ReadFecHeader(
    ForwardErrorCorrection::ReceivedFecPacket* fec_packet) const {
  // Protected ssrcs should already be populated from RTP header.
  if (fec_packet->protected_streams.empty()) {
    RTC_LOG(LS_WARNING)
        << "Discarding FlexFEC packet with no protected sources.";
    return false;
  }
  if (fec_packet->pkt->data.size() <=
      kBaseHeaderSize + kStreamSpecificHeaderSize) {
    RTC_LOG(LS_WARNING) << "Discarding truncated FlexFEC packet.";
    return false;
  }
  uint8_t* const data = fec_packet->pkt->data.MutableData();
  bool r_bit = (data[0] & 0x80) != 0;
  if (r_bit) {
    RTC_LOG(LS_INFO)
        << "FlexFEC packet with retransmission bit set. We do not yet "
           "support this, thus discarding the packet.";
    return false;
  }
  bool f_bit = (data[0] & 0x40) != 0;
  if (f_bit) {
    RTC_LOG(LS_INFO)
        << "FlexFEC packet with inflexible generator matrix. We do "
           "not yet support this, thus discarding packet.";
    return false;
  }

  // First seq_num will be in byte index 8
  // (See FEC header schematic in flexfec_header_reader_writer.h.)
  size_t byte_index = 8;
  for (size_t i = 0; i < fec_packet->protected_streams.size(); ++i) {
    if (fec_packet->pkt->data.size() < byte_index + kStreamSpecificHeaderSize) {
      RTC_LOG(LS_WARNING) << "Discarding truncated FlexFEC packet.";
      return false;
    }

    fec_packet->protected_streams[i].seq_num_base =
        ByteReader<uint16_t>::ReadBigEndian(&data[byte_index]);
    byte_index += kStreamSpecificHeaderSize;

    // Parse the FlexFEC packet mask and remove the interleaved K-bits.
    // (See FEC header schematic in flexfec_header_reader_writer.h.)
    // We store the packed packet mask in-band, which "destroys" the standards
    // compliance of the header. That is fine though, since the code that
    // reads from the header (from this point and onwards) is aware of this.
    // TODO(brandtr): When the FEC packet classes have been refactored, store
    // the packed packet masks out-of-band, thus leaving the FlexFEC header as
    // is.
    //
    // We treat the mask parts as unsigned integers with host order endianness
    // in order to simplify the bit shifting between bytes.
    if (fec_packet->pkt->data.size() <
        (byte_index + kFlexfecPacketMaskSizes[0])) {
      RTC_LOG(LS_WARNING) << "Discarding truncated FlexFEC packet.";
      return false;
    }
    fec_packet->protected_streams[i].packet_mask_offset = byte_index;
    bool k_bit0 = (data[byte_index] & 0x80) != 0;
    uint16_t mask_part0 =
        ByteReader<uint16_t>::ReadBigEndian(&data[byte_index]);
    // Shift away K-bit 0, implicitly clearing the last bit.
    mask_part0 <<= 1;
    ByteWriter<uint16_t>::WriteBigEndian(&data[byte_index], mask_part0);
    byte_index += kFlexfecPacketMaskSizes[0];
    if (k_bit0) {
      // The first K-bit is set, and the packet mask is thus only 2 bytes long.
      // We have finished reading the properties for current ssrc.
      fec_packet->protected_streams[i].packet_mask_size =
          kFlexfecPacketMaskSizes[0];
    } else {
      if (fec_packet->pkt->data.size() <
          (byte_index + kFlexfecPacketMaskSizes[1] -
           kFlexfecPacketMaskSizes[0])) {
        return false;
      }
      bool k_bit1 = (data[byte_index] & 0x80) != 0;
      // We have already shifted the first two bytes of the packet mask one step
      // to the left, thus removing K-bit 0. We will now shift the next four
      // bytes of the packet mask two steps to the left. (One step for the
      // removed K-bit 0, and one step for the to be removed K-bit 1).
      uint8_t bit15 = (data[byte_index] >> 6) & 0x01;
      data[byte_index - 1] |= bit15;
      uint32_t mask_part1 =
          ByteReader<uint32_t>::ReadBigEndian(&data[byte_index]);
      // Shift away K-bit 1 and bit 15, implicitly clearing the last two bits.
      mask_part1 <<= 2;
      ByteWriter<uint32_t>::WriteBigEndian(&data[byte_index], mask_part1);
      byte_index += kFlexfecPacketMaskSizes[1] - kFlexfecPacketMaskSizes[0];
      if (k_bit1) {
        // The first K-bit is clear, but the second K-bit is set. The packet
        // mask is thus 6 bytes long. We have finished reading the properties
        // for current ssrc.
        fec_packet->protected_streams[i].packet_mask_size =
            kFlexfecPacketMaskSizes[1];
      } else {
        if (fec_packet->pkt->data.size() <
            (byte_index + kFlexfecPacketMaskSizes[2] -
             kFlexfecPacketMaskSizes[1])) {
          RTC_LOG(LS_WARNING) << "Discarding truncated FlexFEC packet.";
          return false;
        }
        fec_packet->protected_streams[i].packet_mask_size =
            kFlexfecPacketMaskSizes[2];
        // At this point, K-bits 0 and 1 have been removed, and the front-most
        // part of the FlexFEC packet mask has been packed accordingly. We will
        // now shift the remaning part of the packet mask two steps to the left.
        // This corresponds to the (in total) two K-bits, which have been
        // removed.
        uint8_t tail_bits = (data[byte_index] >> 6) & 0x03;
        data[byte_index - 1] |= tail_bits;
        uint64_t mask_part2 =
            ByteReader<uint64_t>::ReadBigEndian(&data[byte_index]);
        // Shift away bit 46, and bit 47, which were copied to the previous
        // part of the mask, implicitly clearing the last two bits.
        mask_part2 <<= 2;
        ByteWriter<uint64_t>::WriteBigEndian(&data[byte_index], mask_part2);
        byte_index += kFlexfecPacketMaskSizes[2] - kFlexfecPacketMaskSizes[1];
      }
    }
  }

  fec_packet->fec_header_size = byte_index;

  // In FlexFEC, all media packets are protected in their entirety.
  fec_packet->protection_length =
      fec_packet->pkt->data.size() - fec_packet->fec_header_size;

  return true;
}

FlexfecHeaderWriter2::FlexfecHeaderWriter2()
    : FecHeaderWriter(kMaxMediaPackets, kMaxFecPackets, kHeaderSizes[2]) {}

FlexfecHeaderWriter2::~FlexfecHeaderWriter2() = default;

size_t FlexfecHeaderWriter2::MinPacketMaskSize(const uint8_t* packet_mask,
                                               size_t packet_mask_size) const {
  if (packet_mask_size == kUlpfecPacketMaskSizeLBitClear &&
      (packet_mask[1] & 0x01) == 0) {
    // Packet mask is 16 bits long, with bit 15 clear.
    // It can be used as is.
    return kFlexfecPacketMaskSizes[0];
  } else if (packet_mask_size == kUlpfecPacketMaskSizeLBitClear) {
    // Packet mask is 16 bits long, with bit 15 set.
    // We must expand the packet mask with zeros in the FlexFEC header.
    return kFlexfecPacketMaskSizes[1];
  } else if (packet_mask_size == kUlpfecPacketMaskSizeLBitSet &&
             (packet_mask[5] & 0x03) == 0) {
    // Packet mask is 48 bits long, with bits 46 and 47 clear.
    // It can be used as is.
    return kFlexfecPacketMaskSizes[1];
  } else if (packet_mask_size == kUlpfecPacketMaskSizeLBitSet) {
    // Packet mask is 48 bits long, with at least one of bits 46 and 47 set.
    // We must expand it with zeros.
    return kFlexfecPacketMaskSizes[2];
  }
  RTC_DCHECK_NOTREACHED() << "Incorrect packet mask size: " << packet_mask_size
                          << ".";
  return kFlexfecPacketMaskSizes[2];
}

size_t FlexfecHeaderWriter2::FecHeaderSize(size_t packet_mask_size) const {
  return FlexfecHeaderSize(packet_mask_size);
}

// This function adapts the precomputed ULPFEC packet masks to the
// FlexFEC header standard. Note that the header size is computed by
// FecHeaderSize(), so in this function we can be sure that we are
// writing in space that is intended for the header.
//
// TODO(brandtr): Update this function when we support offset-based masks,
// retransmissions, and protecting multiple SSRCs.
void FlexfecHeaderWriter2::FinalizeFecHeader(
    uint32_t media_ssrc,
    uint16_t seq_num_base,
    const uint8_t* packet_mask,
    size_t packet_mask_size,
    ForwardErrorCorrection::Packet* fec_packet) const {
  uint8_t* data = fec_packet->data.MutableData();
  data[0] &= 0x7f;  // Clear R bit.
  data[0] &= 0xbf;  // Clear F bit.
  ByteWriter<uint8_t>::WriteBigEndian(&data[8], kSsrcCount);
  ByteWriter<uint32_t, 3>::WriteBigEndian(&data[9], kReservedBits);
  ByteWriter<uint32_t>::WriteBigEndian(&data[12], media_ssrc);
  ByteWriter<uint16_t>::WriteBigEndian(&data[16], seq_num_base);
  // Adapt ULPFEC packet mask to FlexFEC header.
  //
  // We treat the mask parts as unsigned integers with host order endianness
  // in order to simplify the bit shifting between bytes.
  uint8_t* const written_packet_mask = data + kPacketMaskOffset;
  if (packet_mask_size == kUlpfecPacketMaskSizeLBitSet) {
    // The packet mask is 48 bits long.
    uint16_t tmp_mask_part0 =
        ByteReader<uint16_t>::ReadBigEndian(&packet_mask[0]);
    uint32_t tmp_mask_part1 =
        ByteReader<uint32_t>::ReadBigEndian(&packet_mask[2]);

    tmp_mask_part0 >>= 1;  // Shift, thus clearing K-bit 0.
    ByteWriter<uint16_t>::WriteBigEndian(&written_packet_mask[0],
                                         tmp_mask_part0);
    tmp_mask_part1 >>= 2;  // Shift, thus clearing K-bit 1 and bit 15.
    ByteWriter<uint32_t>::WriteBigEndian(&written_packet_mask[2],
                                         tmp_mask_part1);
    bool bit15 = (packet_mask[1] & 0x01) != 0;
    if (bit15)
      written_packet_mask[2] |= 0x40;  // Set bit 15.
    bool bit46 = (packet_mask[5] & 0x02) != 0;
    bool bit47 = (packet_mask[5] & 0x01) != 0;
    if (!bit46 && !bit47) {
      written_packet_mask[2] |= 0x80;  // Set K-bit 1.
    } else {
      memset(&written_packet_mask[6], 0, 8);  // Clear all trailing bits.
      written_packet_mask[6] |= 0x80;         // Set K-bit 2.
      if (bit46)
        written_packet_mask[6] |= 0x40;  // Set bit 46.
      if (bit47)
        written_packet_mask[6] |= 0x20;  // Set bit 47.
    }
  } else if (packet_mask_size == kUlpfecPacketMaskSizeLBitClear) {
    // The packet mask is 16 bits long.
    uint16_t tmp_mask_part0 =
        ByteReader<uint16_t>::ReadBigEndian(&packet_mask[0]);

    tmp_mask_part0 >>= 1;  // Shift, thus clearing K-bit 0.
    ByteWriter<uint16_t>::WriteBigEndian(&written_packet_mask[0],
                                         tmp_mask_part0);
    bool bit15 = (packet_mask[1] & 0x01) != 0;
    if (!bit15) {
      written_packet_mask[0] |= 0x80;  // Set K-bit 0.
    } else {
      memset(&written_packet_mask[2], 0U, 4);  // Clear all trailing bits.
      written_packet_mask[2] |= 0x80;          // Set K-bit 1.
      written_packet_mask[2] |= 0x40;          // Set bit 15.
    }
  } else {
    RTC_DCHECK_NOTREACHED()
        << "Incorrect packet mask size: " << packet_mask_size << ".";
  }
}

}  // namespace webrtc
