/*
 *  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.
 */

#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h"

#include <utility>

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

namespace webrtc {
namespace rtcp {
constexpr uint8_t SenderReport::kPacketType;
constexpr size_t SenderReport::kMaxNumberOfReportBlocks;
//    Sender report (SR) (RFC 3550).
//     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   |   PT=SR=200   |             length            |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  0 |                         SSRC of sender                        |
//    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//  4 |              NTP timestamp, most significant word             |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  8 |             NTP timestamp, least significant word             |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 12 |                         RTP timestamp                         |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 16 |                     sender's packet count                     |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 20 |                      sender's octet count                     |
// 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

SenderReport::SenderReport()
    : sender_ssrc_(0),
      rtp_timestamp_(0),
      sender_packet_count_(0),
      sender_octet_count_(0) {}

SenderReport::~SenderReport() = default;

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

  const uint8_t report_block_count = packet.count();
  if (packet.payload_size_bytes() <
      kSenderBaseLength + report_block_count * ReportBlock::kLength) {
    LOG(LS_WARNING) << "Packet is too small to contain all the data.";
    return false;
  }
  // Read SenderReport header.
  const uint8_t* const payload = packet.payload();
  sender_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&payload[0]);
  uint32_t secs = ByteReader<uint32_t>::ReadBigEndian(&payload[4]);
  uint32_t frac = ByteReader<uint32_t>::ReadBigEndian(&payload[8]);
  ntp_.Set(secs, frac);
  rtp_timestamp_ = ByteReader<uint32_t>::ReadBigEndian(&payload[12]);
  sender_packet_count_ = ByteReader<uint32_t>::ReadBigEndian(&payload[16]);
  sender_octet_count_ = ByteReader<uint32_t>::ReadBigEndian(&payload[20]);
  report_blocks_.resize(report_block_count);
  const uint8_t* next_block = payload + kSenderBaseLength;
  for (ReportBlock& block : report_blocks_) {
    bool block_parsed = block.Parse(next_block, ReportBlock::kLength);
    RTC_DCHECK(block_parsed);
    next_block += ReportBlock::kLength;
  }
  // Double check we didn't read beyond provided buffer.
  RTC_DCHECK_LE(next_block - payload,
                static_cast<ptrdiff_t>(packet.payload_size_bytes()));
  return true;
}

size_t SenderReport::BlockLength() const {
  return kHeaderLength + kSenderBaseLength +
         report_blocks_.size() * ReportBlock::kLength;
}

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

  CreateHeader(report_blocks_.size(), kPacketType, HeaderLength(), packet,
               index);
  // Write SenderReport header.
  ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 0], sender_ssrc_);
  ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 4], ntp_.seconds());
  ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 8], ntp_.fractions());
  ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 12], rtp_timestamp_);
  ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 16],
                                       sender_packet_count_);
  ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 20],
                                       sender_octet_count_);
  *index += kSenderBaseLength;
  // Write report blocks.
  for (const ReportBlock& block : report_blocks_) {
    block.Create(packet + *index);
    *index += ReportBlock::kLength;
  }
  // Ensure bytes written match expected.
  RTC_DCHECK_EQ(*index, index_end);
  return true;
}

bool SenderReport::AddReportBlock(const ReportBlock& block) {
  if (report_blocks_.size() >= kMaxNumberOfReportBlocks) {
    LOG(LS_WARNING) << "Max report blocks reached.";
    return false;
  }
  report_blocks_.push_back(block);
  return true;
}

bool SenderReport::SetReportBlocks(std::vector<ReportBlock> blocks) {
  if (blocks.size() > kMaxNumberOfReportBlocks) {
    LOG(LS_WARNING) << "Too many report blocks (" << blocks.size()
                    << ") for sender report.";
    return false;
  }
  report_blocks_ = std::move(blocks);
  return true;
}

}  // namespace rtcp
}  // namespace webrtc
