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

#include <utility>

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

using testing::ElementsAreArray;
using testing::make_tuple;
using webrtc::rtcp::ReportBlock;
using webrtc::rtcp::SenderReport;

namespace webrtc {
namespace {
const uint32_t kSenderSsrc = 0x12345678;
const uint32_t kRemoteSsrc = 0x23456789;
const NtpTime kNtp(0x11121418, 0x22242628);
const uint32_t kRtpTimestamp = 0x33343536;
const uint32_t kPacketCount = 0x44454647;
const uint32_t kOctetCount = 0x55565758;
const uint8_t kPacket[] = {0x80, 200,  0x00, 0x06, 0x12, 0x34, 0x56,
                           0x78, 0x11, 0x12, 0x14, 0x18, 0x22, 0x24,
                           0x26, 0x28, 0x33, 0x34, 0x35, 0x36, 0x44,
                           0x45, 0x46, 0x47, 0x55, 0x56, 0x57, 0x58};
}  // namespace

TEST(RtcpPacketSenderReportTest, CreateWithoutReportBlocks) {
  SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  sr.SetNtp(kNtp);
  sr.SetRtpTimestamp(kRtpTimestamp);
  sr.SetPacketCount(kPacketCount);
  sr.SetOctetCount(kOctetCount);

  rtc::Buffer raw = sr.Build();
  EXPECT_THAT(make_tuple(raw.data(), raw.size()), ElementsAreArray(kPacket));
}

TEST(RtcpPacketSenderReportTest, ParseWithoutReportBlocks) {
  SenderReport parsed;
  EXPECT_TRUE(test::ParseSinglePacket(kPacket, &parsed));

  EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
  EXPECT_EQ(kNtp, parsed.ntp());
  EXPECT_EQ(kRtpTimestamp, parsed.rtp_timestamp());
  EXPECT_EQ(kPacketCount, parsed.sender_packet_count());
  EXPECT_EQ(kOctetCount, parsed.sender_octet_count());
  EXPECT_TRUE(parsed.report_blocks().empty());
}

TEST(RtcpPacketSenderReportTest, CreateAndParseWithOneReportBlock) {
  ReportBlock rb;
  rb.SetMediaSsrc(kRemoteSsrc);

  SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  EXPECT_TRUE(sr.AddReportBlock(rb));

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

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

TEST(RtcpPacketSenderReportTest, CreateAndParseWithTwoReportBlocks) {
  ReportBlock rb1;
  rb1.SetMediaSsrc(kRemoteSsrc);
  ReportBlock rb2;
  rb2.SetMediaSsrc(kRemoteSsrc + 1);

  SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  EXPECT_TRUE(sr.AddReportBlock(rb1));
  EXPECT_TRUE(sr.AddReportBlock(rb2));

  rtc::Buffer raw = sr.Build();
  SenderReport 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(RtcpPacketSenderReportTest, CreateWithTooManyReportBlocks) {
  SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  ReportBlock rb;
  for (size_t i = 0; i < SenderReport::kMaxNumberOfReportBlocks; ++i) {
    rb.SetMediaSsrc(kRemoteSsrc + i);
    EXPECT_TRUE(sr.AddReportBlock(rb));
  }
  rb.SetMediaSsrc(kRemoteSsrc + SenderReport::kMaxNumberOfReportBlocks);
  EXPECT_FALSE(sr.AddReportBlock(rb));
}

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

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

TEST(RtcpPacketSenderReportTest, SetReportBlocksMaxLimit) {
  SenderReport sr;
  std::vector<ReportBlock> max_blocks(SenderReport::kMaxNumberOfReportBlocks);
  EXPECT_TRUE(sr.SetReportBlocks(std::move(max_blocks)));

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

}  // namespace webrtc
