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

#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {
namespace rtcp {
constexpr uint8_t LossNotification::kFeedbackMessageType;

// Loss Notification
// -----------------
//     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| FMT=15  |   PT=206      |             length            |
//    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//  0 |                  SSRC of packet sender                        |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  4 |                  SSRC of media source                         |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  8 |  Unique identifier 'L' 'N' 'T' 'F'                            |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 12 | Last Decoded Sequence Number  | Last Received SeqNum Delta  |D|
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

LossNotification::LossNotification()
    : last_decoded_(0), last_received_(0), decodability_flag_(false) {}

LossNotification::LossNotification(const LossNotification& rhs) = default;

LossNotification::~LossNotification() = default;

size_t LossNotification::BlockLength() const {
  return kHeaderLength + kCommonFeedbackLength + kLossNotificationPayloadLength;
}

bool LossNotification::Create(uint8_t* packet,
                              size_t* index,
                              size_t max_length,
                              PacketReadyCallback callback) const {
  while (*index + BlockLength() > max_length) {
    if (!OnBufferFull(packet, index, callback))
      return false;
  }

  const size_t index_end = *index + BlockLength();

  // Note: |index| updated by the function below.
  CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet,
               index);

  CreateCommonFeedback(packet + *index);
  *index += kCommonFeedbackLength;

  ByteWriter<uint32_t>::WriteBigEndian(packet + *index, kUniqueIdentifier);
  *index += sizeof(uint32_t);

  ByteWriter<uint16_t>::WriteBigEndian(packet + *index, last_decoded_);
  *index += sizeof(uint16_t);

  const uint16_t last_received_delta = last_received_ - last_decoded_;
  RTC_DCHECK_LE(last_received_delta, 0x7fff);
  const uint16_t last_received_delta_and_decodability =
      (last_received_delta << 1) | (decodability_flag_ ? 0x0001 : 0x0000);

  ByteWriter<uint16_t>::WriteBigEndian(packet + *index,
                                       last_received_delta_and_decodability);
  *index += sizeof(uint16_t);

  RTC_DCHECK_EQ(index_end, *index);
  return true;
}

bool LossNotification::Parse(const CommonHeader& packet) {
  RTC_DCHECK_EQ(packet.type(), kPacketType);
  RTC_DCHECK_EQ(packet.fmt(), kFeedbackMessageType);

  if (packet.payload_size_bytes() <
      kCommonFeedbackLength + kLossNotificationPayloadLength) {
    return false;
  }

  const uint8_t* const payload = packet.payload();

  if (ByteReader<uint32_t>::ReadBigEndian(&payload[8]) != kUniqueIdentifier) {
    return false;
  }

  ParseCommonFeedback(payload);

  last_decoded_ = ByteReader<uint16_t>::ReadBigEndian(&payload[12]);

  const uint16_t last_received_delta_and_decodability =
      ByteReader<uint16_t>::ReadBigEndian(&payload[14]);
  last_received_ = last_decoded_ + (last_received_delta_and_decodability >> 1);
  decodability_flag_ = (last_received_delta_and_decodability & 0x0001);

  return true;
}

bool LossNotification::Set(uint16_t last_decoded,
                           uint16_t last_received,
                           bool decodability_flag) {
  const uint16_t delta = last_received - last_decoded;
  if (delta > 0x7fff) {
    return false;
  }
  last_received_ = last_received;
  last_decoded_ = last_decoded;
  decodability_flag_ = decodability_flag;
  return true;
}

}  // namespace rtcp
}  // namespace webrtc
