/*
 *  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 "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"

#include <utility>

#include "test/gmock.h"
#include "test/gtest.h"
#include "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
