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

#include <utility>

#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"
#include "webrtc/test/rtcp_packet_parser.h"

using testing::ElementsAreArray;
using testing::IsEmpty;
using testing::make_tuple;
using webrtc::rtcp::ReceiverReport;
using webrtc::rtcp::ReportBlock;

namespace webrtc {
namespace {
const uint32_t kSenderSsrc = 0x12345678;
const uint32_t kRemoteSsrc = 0x23456789;
const uint8_t kFractionLost = 55;
const uint32_t kCumulativeLost = 0x111213;
const uint32_t kExtHighestSeqNum = 0x22232425;
const uint32_t kJitter = 0x33343536;
const uint32_t kLastSr = 0x44454647;
const uint32_t kDelayLastSr = 0x55565758;
// Manually created ReceiverReport with one ReportBlock matching constants
// above.
// Having this block allows to test Create and Parse separately.
const uint8_t kPacket[] = {0x81, 201,  0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
                           0x23, 0x45, 0x67, 0x89, 55,   0x11, 0x12, 0x13,
                           0x22, 0x23, 0x24, 0x25, 0x33, 0x34, 0x35, 0x36,
                           0x44, 0x45, 0x46, 0x47, 0x55, 0x56, 0x57, 0x58};
}  // namespace

TEST(RtcpPacketReceiverReportTest, ParseWithOneReportBlock) {
  ReceiverReport rr;
  EXPECT_TRUE(test::ParseSinglePacket(kPacket, &rr));
  const ReceiverReport& parsed = rr;

  EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
  EXPECT_EQ(1u, parsed.report_blocks().size());
  const ReportBlock& rb = parsed.report_blocks().front();
  EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
  EXPECT_EQ(kFractionLost, rb.fraction_lost());
  EXPECT_EQ(kCumulativeLost, rb.cumulative_lost());
  EXPECT_EQ(kExtHighestSeqNum, rb.extended_high_seq_num());
  EXPECT_EQ(kJitter, rb.jitter());
  EXPECT_EQ(kLastSr, rb.last_sr());
  EXPECT_EQ(kDelayLastSr, rb.delay_since_last_sr());
}

TEST(RtcpPacketReceiverReportTest, ParseFailsOnIncorrectSize) {
  rtc::Buffer damaged_packet(kPacket);
  damaged_packet[0]++;  // Damage the packet: increase count field.
  ReceiverReport rr;
  EXPECT_FALSE(test::ParseSinglePacket(damaged_packet, &rr));
}

TEST(RtcpPacketReceiverReportTest, CreateWithOneReportBlock) {
  ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);
  ReportBlock rb;
  rb.SetMediaSsrc(kRemoteSsrc);
  rb.SetFractionLost(kFractionLost);
  rb.SetCumulativeLost(kCumulativeLost);
  rb.SetExtHighestSeqNum(kExtHighestSeqNum);
  rb.SetJitter(kJitter);
  rb.SetLastSr(kLastSr);
  rb.SetDelayLastSr(kDelayLastSr);
  rr.AddReportBlock(rb);

  rtc::Buffer raw = rr.Build();

  EXPECT_THAT(make_tuple(raw.data(), raw.size()), ElementsAreArray(kPacket));
}

TEST(RtcpPacketReceiverReportTest, CreateAndParseWithoutReportBlocks) {
  ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);

  rtc::Buffer raw = rr.Build();
  ReceiverReport parsed;
  EXPECT_TRUE(test::ParseSinglePacket(raw, &parsed));

  EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
  EXPECT_THAT(parsed.report_blocks(), IsEmpty());
}

TEST(RtcpPacketReceiverReportTest, CreateAndParseWithTwoReportBlocks) {
  ReceiverReport rr;
  ReportBlock rb1;
  rb1.SetMediaSsrc(kRemoteSsrc);
  ReportBlock rb2;
  rb2.SetMediaSsrc(kRemoteSsrc + 1);

  rr.SetSenderSsrc(kSenderSsrc);
  EXPECT_TRUE(rr.AddReportBlock(rb1));
  EXPECT_TRUE(rr.AddReportBlock(rb2));

  rtc::Buffer raw = rr.Build();
  ReceiverReport parsed;
  EXPECT_TRUE(test::ParseSinglePacket(raw, &parsed));

  EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
  EXPECT_EQ(2u, parsed.report_blocks().size());
  EXPECT_EQ(kRemoteSsrc, parsed.report_blocks()[0].source_ssrc());
  EXPECT_EQ(kRemoteSsrc + 1, parsed.report_blocks()[1].source_ssrc());
}

TEST(RtcpPacketReceiverReportTest, CreateWithTooManyReportBlocks) {
  ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);
  ReportBlock rb;
  for (size_t i = 0; i < ReceiverReport::kMaxNumberOfReportBlocks; ++i) {
    rb.SetMediaSsrc(kRemoteSsrc + i);
    EXPECT_TRUE(rr.AddReportBlock(rb));
  }
  rb.SetMediaSsrc(kRemoteSsrc + ReceiverReport::kMaxNumberOfReportBlocks);
  EXPECT_FALSE(rr.AddReportBlock(rb));
}

TEST(RtcpPacketReceiverReportTest, SetReportBlocksOverwritesOldBlocks) {
  ReceiverReport rr;
  ReportBlock report_block;
  // Use jitter field of the report blocks to distinguish them.
  report_block.SetJitter(1001u);
  rr.AddReportBlock(report_block);
  ASSERT_EQ(rr.report_blocks().size(), 1u);
  ASSERT_EQ(rr.report_blocks()[0].jitter(), 1001u);

  std::vector<ReportBlock> blocks(3u);
  blocks[0].SetJitter(2001u);
  blocks[1].SetJitter(3001u);
  blocks[2].SetJitter(4001u);
  EXPECT_TRUE(rr.SetReportBlocks(blocks));
  ASSERT_EQ(rr.report_blocks().size(), 3u);
  EXPECT_EQ(rr.report_blocks()[0].jitter(), 2001u);
  EXPECT_EQ(rr.report_blocks()[1].jitter(), 3001u);
  EXPECT_EQ(rr.report_blocks()[2].jitter(), 4001u);
}

TEST(RtcpPacketReceiverReportTest, SetReportBlocksMaxLimit) {
  ReceiverReport rr;
  std::vector<ReportBlock> max_blocks(ReceiverReport::kMaxNumberOfReportBlocks);
  EXPECT_TRUE(rr.SetReportBlocks(std::move(max_blocks)));

  std::vector<ReportBlock> one_too_many_blocks(
      ReceiverReport::kMaxNumberOfReportBlocks + 1);
  EXPECT_FALSE(rr.SetReportBlocks(std::move(one_too_many_blocks)));
}

}  // namespace webrtc
