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

#include <memory>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "api/rtp_headers.h"
#include "api/test/create_time_controller.h"
#include "api/test/time_controller.h"
#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/video_bitrate_allocation.h"
#include "modules/rtp_rtcp/include/receive_statistics.h"
#include "modules/rtp_rtcp/include/report_block_data.h"
#include "modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h"
#include "modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h"
#include "modules/rtp_rtcp/source/ntp_time_util.h"
#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
#include "system_wrappers/include/clock.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/rtcp_packet_parser.h"

namespace webrtc {
namespace {

using ::testing::_;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::Ge;
using ::testing::MockFunction;
using ::testing::NiceMock;
using ::testing::Property;
using ::testing::Return;
using ::testing::SizeIs;
using ::testing::StrictMock;
using ::testing::UnorderedElementsAre;
using ::testing::WithArg;
using ::webrtc::rtcp::Bye;
using ::webrtc::rtcp::CompoundPacket;
using ::webrtc::rtcp::ReportBlock;
using ::webrtc::rtcp::SenderReport;
using ::webrtc::test::RtcpPacketParser;

class MockReceiveStatisticsProvider : public ReceiveStatisticsProvider {
 public:
  MOCK_METHOD(std::vector<ReportBlock>, RtcpReportBlocks, (size_t), (override));
};

class MockMediaReceiverRtcpObserver : public MediaReceiverRtcpObserver {
 public:
  MOCK_METHOD(void, OnSenderReport, (uint32_t, NtpTime, uint32_t), (override));
  MOCK_METHOD(void, OnBye, (uint32_t), (override));
  MOCK_METHOD(void,
              OnBitrateAllocation,
              (uint32_t, const VideoBitrateAllocation&),
              (override));
};

class MockRtpStreamRtcpHandler : public RtpStreamRtcpHandler {
 public:
  MockRtpStreamRtcpHandler() {
    // With each next call increase number of sent packets and bytes to simulate
    // active RTP sender.
    ON_CALL(*this, SentStats).WillByDefault([this] {
      RtpStats stats;
      stats.set_num_sent_packets(++num_calls_);
      stats.set_num_sent_bytes(1'000 * num_calls_);
      return stats;
    });
  }

  MOCK_METHOD(RtpStats, SentStats, (), (override));
  MOCK_METHOD(void,
              OnNack,
              (uint32_t, rtc::ArrayView<const uint16_t>),
              (override));
  MOCK_METHOD(void, OnFir, (uint32_t), (override));
  MOCK_METHOD(void, OnPli, (uint32_t), (override));
  MOCK_METHOD(void, OnReport, (const ReportBlockData&), (override));

 private:
  int num_calls_ = 0;
};

constexpr TimeDelta kReportPeriod = TimeDelta::Seconds(1);
constexpr TimeDelta kAlmostForever = TimeDelta::Seconds(2);
constexpr TimeDelta kTimePrecision = TimeDelta::Millis(1);

MATCHER_P(Near, value, "") {
  return arg > value - kTimePrecision && arg < value + kTimePrecision;
}

// Helper to wait for an rtcp packet produced on a different thread/task queue.
class FakeRtcpTransport {
 public:
  explicit FakeRtcpTransport(TimeController& time) : time_(time) {}

  std::function<void(rtc::ArrayView<const uint8_t>)> AsStdFunction() {
    return [this](rtc::ArrayView<const uint8_t>) { sent_rtcp_ = true; };
  }

  // Returns true when packet was received by the transport.
  bool WaitPacket() {
    bool got_packet = time_.Wait([this] { return sent_rtcp_; }, kAlmostForever);
    // Clear the 'event' to allow waiting for multiple packets.
    sent_rtcp_ = false;
    return got_packet;
  }

 private:
  TimeController& time_;
  bool sent_rtcp_ = false;
};

std::function<void(rtc::ArrayView<const uint8_t>)> RtcpParserTransport(
    RtcpPacketParser& parser) {
  return [&parser](rtc::ArrayView<const uint8_t> packet) {
    return parser.Parse(packet);
  };
}

class RtcpTransceiverImplTest : public ::testing::Test {
 public:
  RtcpTransceiverConfig DefaultTestConfig() {
    // RtcpTransceiverConfig default constructor sets default values for prod.
    // Test doesn't need to support all key features: Default test config
    // returns valid config with all features turned off.
    RtcpTransceiverConfig config;
    config.clock = time_->GetClock();
    config.schedule_periodic_compound_packets = false;
    config.initial_report_delay = kReportPeriod / 2;
    config.report_period = kReportPeriod;
    return config;
  }

  TimeController& time_controller() { return *time_; }
  Timestamp CurrentTime() { return time_->GetClock()->CurrentTime(); }
  void AdvanceTime(TimeDelta time) { time_->AdvanceTime(time); }
  std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue() {
    return time_->GetTaskQueueFactory()->CreateTaskQueue(
        "rtcp", TaskQueueFactory::Priority::NORMAL);
  }

 private:
  std::unique_ptr<TimeController> time_ = CreateSimulatedTimeController();
};

TEST_F(RtcpTransceiverImplTest, NeedToStopPeriodicTaskToDestroyOnTaskQueue) {
  FakeRtcpTransport transport(time_controller());
  auto queue = CreateTaskQueue();
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.task_queue = queue.get();
  config.schedule_periodic_compound_packets = true;
  config.rtcp_transport = transport.AsStdFunction();
  auto* rtcp_transceiver = new RtcpTransceiverImpl(config);
  // Wait for a periodic packet.
  EXPECT_TRUE(transport.WaitPacket());

  bool done = false;
  queue->PostTask([rtcp_transceiver, &done] {
    rtcp_transceiver->StopPeriodicTask();
    delete rtcp_transceiver;
    done = true;
  });
  ASSERT_TRUE(time_controller().Wait([&] { return done; }, kAlmostForever));
}

TEST_F(RtcpTransceiverImplTest, CanBeDestroyedRightAfterCreation) {
  FakeRtcpTransport transport(time_controller());
  auto queue = CreateTaskQueue();
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.task_queue = queue.get();
  config.schedule_periodic_compound_packets = true;
  config.rtcp_transport = transport.AsStdFunction();

  bool done = false;
  queue->PostTask([&] {
    RtcpTransceiverImpl rtcp_transceiver(config);
    rtcp_transceiver.StopPeriodicTask();
    done = true;
  });
  ASSERT_TRUE(time_controller().Wait([&] { return done; }, kAlmostForever));
}

TEST_F(RtcpTransceiverImplTest, CanDestroyAfterTaskQueue) {
  FakeRtcpTransport transport(time_controller());
  auto queue = CreateTaskQueue();

  RtcpTransceiverConfig config = DefaultTestConfig();
  config.task_queue = queue.get();
  config.schedule_periodic_compound_packets = true;
  config.rtcp_transport = transport.AsStdFunction();
  auto* rtcp_transceiver = new RtcpTransceiverImpl(config);
  // Wait for a periodic packet.
  EXPECT_TRUE(transport.WaitPacket());

  queue = nullptr;
  delete rtcp_transceiver;
}

TEST_F(RtcpTransceiverImplTest, DelaysSendingFirstCompondPacket) {
  auto queue = CreateTaskQueue();
  FakeRtcpTransport transport(time_controller());
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = true;
  config.rtcp_transport = transport.AsStdFunction();
  config.initial_report_delay = TimeDelta::Millis(10);
  config.task_queue = queue.get();
  std::optional<RtcpTransceiverImpl> rtcp_transceiver;

  Timestamp started = CurrentTime();
  queue->PostTask([&] { rtcp_transceiver.emplace(config); });
  EXPECT_TRUE(transport.WaitPacket());

  EXPECT_GE(CurrentTime() - started, config.initial_report_delay);

  // Cleanup.
  bool done = false;
  queue->PostTask([&] {
    rtcp_transceiver->StopPeriodicTask();
    rtcp_transceiver.reset();
    done = true;
  });
  ASSERT_TRUE(time_controller().Wait([&] { return done; }, kAlmostForever));
}

TEST_F(RtcpTransceiverImplTest, PeriodicallySendsPackets) {
  auto queue = CreateTaskQueue();
  FakeRtcpTransport transport(time_controller());
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = true;
  config.rtcp_transport = transport.AsStdFunction();
  config.initial_report_delay = TimeDelta::Zero();
  config.report_period = kReportPeriod;
  config.task_queue = queue.get();
  std::optional<RtcpTransceiverImpl> rtcp_transceiver;
  Timestamp time_just_before_1st_packet = Timestamp::MinusInfinity();
  queue->PostTask([&] {
    // Because initial_report_delay_ms is set to 0, time_just_before_the_packet
    // should be very close to the time_of_the_packet.
    time_just_before_1st_packet = CurrentTime();
    rtcp_transceiver.emplace(config);
  });

  EXPECT_TRUE(transport.WaitPacket());
  EXPECT_TRUE(transport.WaitPacket());
  Timestamp time_just_after_2nd_packet = CurrentTime();

  EXPECT_GE(time_just_after_2nd_packet - time_just_before_1st_packet,
            config.report_period);

  // Cleanup.
  bool done = false;
  queue->PostTask([&] {
    rtcp_transceiver->StopPeriodicTask();
    rtcp_transceiver.reset();
    done = true;
  });
  ASSERT_TRUE(time_controller().Wait([&] { return done; }, kAlmostForever));
}

TEST_F(RtcpTransceiverImplTest, SendCompoundPacketDelaysPeriodicSendPackets) {
  auto queue = CreateTaskQueue();
  FakeRtcpTransport transport(time_controller());
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = true;
  config.rtcp_transport = transport.AsStdFunction();
  config.initial_report_delay = TimeDelta::Zero();
  config.report_period = kReportPeriod;
  config.task_queue = queue.get();
  std::optional<RtcpTransceiverImpl> rtcp_transceiver;
  queue->PostTask([&] { rtcp_transceiver.emplace(config); });

  // Wait for the first packet.
  EXPECT_TRUE(transport.WaitPacket());
  // Send non periodic one after half period.
  bool non_periodic = false;
  Timestamp time_of_non_periodic_packet = Timestamp::MinusInfinity();
  queue->PostDelayedTask(
      [&] {
        time_of_non_periodic_packet = CurrentTime();
        rtcp_transceiver->SendCompoundPacket();
        non_periodic = true;
      },
      config.report_period / 2);
  // Though non-periodic packet is scheduled just in between periodic, due to
  // small period and task queue flakiness it migth end-up 1ms after next
  // periodic packet. To be sure duration after non-periodic packet is tested
  // wait for transport after ensuring non-periodic packet was sent.
  EXPECT_TRUE(
      time_controller().Wait([&] { return non_periodic; }, kAlmostForever));
  EXPECT_TRUE(transport.WaitPacket());
  // Wait for next periodic packet.
  EXPECT_TRUE(transport.WaitPacket());
  Timestamp time_of_last_periodic_packet = CurrentTime();
  EXPECT_GE(time_of_last_periodic_packet - time_of_non_periodic_packet,
            config.report_period);

  // Cleanup.
  bool done = false;
  queue->PostTask([&] {
    rtcp_transceiver->StopPeriodicTask();
    rtcp_transceiver.reset();
    done = true;
  });
  ASSERT_TRUE(time_controller().Wait([&] { return done; }, kAlmostForever));
}

TEST_F(RtcpTransceiverImplTest, SendsNoRtcpWhenNetworkStateIsDown) {
  MockFunction<void(rtc::ArrayView<const uint8_t>)> mock_transport;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.initial_ready_to_send = false;
  config.rtcp_transport = mock_transport.AsStdFunction();
  RtcpTransceiverImpl rtcp_transceiver(config);

  EXPECT_CALL(mock_transport, Call).Times(0);

  const std::vector<uint16_t> sequence_numbers = {45, 57};
  const uint32_t ssrcs[] = {123};
  rtcp_transceiver.SendCompoundPacket();
  rtcp_transceiver.SendNack(ssrcs[0], sequence_numbers);
  rtcp_transceiver.SendPictureLossIndication(ssrcs[0]);
  rtcp_transceiver.SendFullIntraRequest(ssrcs, true);
}

TEST_F(RtcpTransceiverImplTest, SendsRtcpWhenNetworkStateIsUp) {
  MockFunction<void(rtc::ArrayView<const uint8_t>)> mock_transport;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.initial_ready_to_send = false;
  config.rtcp_transport = mock_transport.AsStdFunction();
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SetReadyToSend(true);

  EXPECT_CALL(mock_transport, Call).Times(4);

  const std::vector<uint16_t> sequence_numbers = {45, 57};
  const uint32_t ssrcs[] = {123};
  rtcp_transceiver.SendCompoundPacket();
  rtcp_transceiver.SendNack(ssrcs[0], sequence_numbers);
  rtcp_transceiver.SendPictureLossIndication(ssrcs[0]);
  rtcp_transceiver.SendFullIntraRequest(ssrcs, true);
}

TEST_F(RtcpTransceiverImplTest, SendsPeriodicRtcpWhenNetworkStateIsUp) {
  auto queue = CreateTaskQueue();
  FakeRtcpTransport transport(time_controller());
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = true;
  config.initial_ready_to_send = false;
  config.rtcp_transport = transport.AsStdFunction();
  config.task_queue = queue.get();
  std::optional<RtcpTransceiverImpl> rtcp_transceiver;
  rtcp_transceiver.emplace(config);

  queue->PostTask([&] { rtcp_transceiver->SetReadyToSend(true); });

  EXPECT_TRUE(transport.WaitPacket());

  // Cleanup.
  bool done = false;
  queue->PostTask([&] {
    rtcp_transceiver->StopPeriodicTask();
    rtcp_transceiver.reset();
    done = true;
  });
  ASSERT_TRUE(time_controller().Wait([&] { return done; }, kAlmostForever));
}

TEST_F(RtcpTransceiverImplTest, SendsMinimalCompoundPacket) {
  const uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  config.cname = "cname";
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();

  // Minimal compound RTCP packet contains sender or receiver report and sdes
  // with cname.
  ASSERT_GT(rtcp_parser.receiver_report()->num_packets(), 0);
  EXPECT_EQ(rtcp_parser.receiver_report()->sender_ssrc(), kSenderSsrc);
  ASSERT_GT(rtcp_parser.sdes()->num_packets(), 0);
  ASSERT_EQ(rtcp_parser.sdes()->chunks().size(), 1u);
  EXPECT_EQ(rtcp_parser.sdes()->chunks()[0].ssrc, kSenderSsrc);
  EXPECT_EQ(rtcp_parser.sdes()->chunks()[0].cname, config.cname);
}

TEST_F(RtcpTransceiverImplTest, AvoidsEmptyPacketsInReducedMode) {
  MockFunction<void(rtc::ArrayView<const uint8_t>)> transport;
  EXPECT_CALL(transport, Call).Times(0);
  NiceMock<MockReceiveStatisticsProvider> receive_statistics;

  RtcpTransceiverConfig config = DefaultTestConfig();
  config.rtcp_transport = transport.AsStdFunction();
  config.rtcp_mode = webrtc::RtcpMode::kReducedSize;
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();
}

TEST_F(RtcpTransceiverImplTest, AvoidsEmptyReceiverReportsInReducedMode) {
  RtcpPacketParser rtcp_parser;
  NiceMock<MockReceiveStatisticsProvider> receive_statistics;

  RtcpTransceiverConfig config = DefaultTestConfig();
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.rtcp_mode = webrtc::RtcpMode::kReducedSize;
  config.receive_statistics = &receive_statistics;
  // Set it to produce something (RRTR) in the "periodic" rtcp packets.
  config.non_sender_rtt_measurement = true;
  RtcpTransceiverImpl rtcp_transceiver(config);

  // Rather than waiting for the right time to produce the periodic packet,
  // trigger it manually.
  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.receiver_report()->num_packets(), 0);
  EXPECT_GT(rtcp_parser.xr()->num_packets(), 0);
}

TEST_F(RtcpTransceiverImplTest, SendsNoRembInitially) {
  const uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 0);
}

TEST_F(RtcpTransceiverImplTest, SetRembIncludesRembInNextCompoundPacket) {
  const uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrcs=*/{54321, 64321});
  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.remb()->sender_ssrc(), kSenderSsrc);
  EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 10000);
  EXPECT_THAT(rtcp_parser.remb()->ssrcs(), ElementsAre(54321, 64321));
}

TEST_F(RtcpTransceiverImplTest, SetRembUpdatesValuesToSend) {
  const uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrcs=*/{54321, 64321});
  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 10000);
  EXPECT_THAT(rtcp_parser.remb()->ssrcs(), ElementsAre(54321, 64321));

  rtcp_transceiver.SetRemb(/*bitrate_bps=*/70000, /*ssrcs=*/{67321});
  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 2);
  EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 70000);
  EXPECT_THAT(rtcp_parser.remb()->ssrcs(), ElementsAre(67321));
}

TEST_F(RtcpTransceiverImplTest, SetRembSendsImmediatelyIfSendRembOnChange) {
  const uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.send_remb_on_change = true;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrcs=*/{});
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.remb()->sender_ssrc(), kSenderSsrc);
  EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 10000);

  // If there is no change, the packet is not sent immediately.
  rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrcs=*/{});
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);

  rtcp_transceiver.SetRemb(/*bitrate_bps=*/20000, /*ssrcs=*/{});
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 2);
  EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 20000);
}

TEST_F(RtcpTransceiverImplTest,
       SetRembSendsImmediatelyIfSendRembOnChangeReducedSize) {
  const uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.send_remb_on_change = true;
  config.rtcp_mode = webrtc::RtcpMode::kReducedSize;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrcs=*/{});
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.remb()->sender_ssrc(), kSenderSsrc);
  EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 10000);
}

TEST_F(RtcpTransceiverImplTest, SetRembIncludesRembInAllCompoundPackets) {
  const uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrcs=*/{54321, 64321});
  rtcp_transceiver.SendCompoundPacket();
  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{2});
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 2);
}

TEST_F(RtcpTransceiverImplTest, SendsNoRembAfterUnset) {
  const uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrcs=*/{54321, 64321});
  rtcp_transceiver.SendCompoundPacket();
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  ASSERT_EQ(rtcp_parser.remb()->num_packets(), 1);

  rtcp_transceiver.UnsetRemb();
  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{2});
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
}

TEST_F(RtcpTransceiverImplTest, ReceiverReportUsesReceiveStatistics) {
  const uint32_t kSenderSsrc = 12345;
  const uint32_t kMediaSsrc = 54321;
  MockReceiveStatisticsProvider receive_statistics;
  std::vector<ReportBlock> report_blocks(1);
  report_blocks[0].SetMediaSsrc(kMediaSsrc);
  EXPECT_CALL(receive_statistics, RtcpReportBlocks(_))
      .WillRepeatedly(Return(report_blocks));

  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.receive_statistics = &receive_statistics;
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();

  ASSERT_GT(rtcp_parser.receiver_report()->num_packets(), 0);
  EXPECT_EQ(rtcp_parser.receiver_report()->sender_ssrc(), kSenderSsrc);
  ASSERT_THAT(rtcp_parser.receiver_report()->report_blocks(),
              SizeIs(report_blocks.size()));
  EXPECT_EQ(rtcp_parser.receiver_report()->report_blocks()[0].source_ssrc(),
            kMediaSsrc);
}

TEST_F(RtcpTransceiverImplTest, MultipleObserversOnSameSsrc) {
  const uint32_t kRemoteSsrc = 12345;
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, &observer1);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, &observer2);

  const NtpTime kRemoteNtp(0x9876543211);
  const uint32_t kRemoteRtp = 0x444555;
  SenderReport sr;
  sr.SetSenderSsrc(kRemoteSsrc);
  sr.SetNtp(kRemoteNtp);
  sr.SetRtpTimestamp(kRemoteRtp);
  auto raw_packet = sr.Build();

  EXPECT_CALL(observer1, OnSenderReport(kRemoteSsrc, kRemoteNtp, kRemoteRtp));
  EXPECT_CALL(observer2, OnSenderReport(kRemoteSsrc, kRemoteNtp, kRemoteRtp));
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));
}

TEST_F(RtcpTransceiverImplTest, DoesntCallsObserverAfterRemoved) {
  const uint32_t kRemoteSsrc = 12345;
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, &observer1);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, &observer2);

  SenderReport sr;
  sr.SetSenderSsrc(kRemoteSsrc);
  auto raw_packet = sr.Build();

  rtcp_transceiver.RemoveMediaReceiverRtcpObserver(kRemoteSsrc, &observer1);

  EXPECT_CALL(observer1, OnSenderReport(_, _, _)).Times(0);
  EXPECT_CALL(observer2, OnSenderReport(_, _, _));
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));
}

TEST_F(RtcpTransceiverImplTest, CallsObserverOnSenderReportBySenderSsrc) {
  const uint32_t kRemoteSsrc1 = 12345;
  const uint32_t kRemoteSsrc2 = 22345;
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc1, &observer1);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc2, &observer2);

  const NtpTime kRemoteNtp(0x9876543211);
  const uint32_t kRemoteRtp = 0x444555;
  SenderReport sr;
  sr.SetSenderSsrc(kRemoteSsrc1);
  sr.SetNtp(kRemoteNtp);
  sr.SetRtpTimestamp(kRemoteRtp);
  auto raw_packet = sr.Build();

  EXPECT_CALL(observer1, OnSenderReport(kRemoteSsrc1, kRemoteNtp, kRemoteRtp));
  EXPECT_CALL(observer2, OnSenderReport).Times(0);
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));
}

TEST_F(RtcpTransceiverImplTest, CallsObserverOnByeBySenderSsrc) {
  const uint32_t kRemoteSsrc1 = 12345;
  const uint32_t kRemoteSsrc2 = 22345;
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc1, &observer1);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc2, &observer2);

  Bye bye;
  bye.SetSenderSsrc(kRemoteSsrc1);
  auto raw_packet = bye.Build();

  EXPECT_CALL(observer1, OnBye(kRemoteSsrc1));
  EXPECT_CALL(observer2, OnBye(_)).Times(0);
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));
}

TEST_F(RtcpTransceiverImplTest, CallsObserverOnTargetBitrateBySenderSsrc) {
  const uint32_t kRemoteSsrc1 = 12345;
  const uint32_t kRemoteSsrc2 = 22345;
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc1, &observer1);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc2, &observer2);

  webrtc::rtcp::TargetBitrate target_bitrate;
  target_bitrate.AddTargetBitrate(0, 0, /*target_bitrate_kbps=*/10);
  target_bitrate.AddTargetBitrate(0, 1, /*target_bitrate_kbps=*/20);
  target_bitrate.AddTargetBitrate(1, 0, /*target_bitrate_kbps=*/40);
  target_bitrate.AddTargetBitrate(1, 1, /*target_bitrate_kbps=*/80);
  webrtc::rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kRemoteSsrc1);
  xr.SetTargetBitrate(target_bitrate);
  auto raw_packet = xr.Build();

  VideoBitrateAllocation bitrate_allocation;
  bitrate_allocation.SetBitrate(0, 0, /*bitrate_bps=*/10000);
  bitrate_allocation.SetBitrate(0, 1, /*bitrate_bps=*/20000);
  bitrate_allocation.SetBitrate(1, 0, /*bitrate_bps=*/40000);
  bitrate_allocation.SetBitrate(1, 1, /*bitrate_bps=*/80000);
  EXPECT_CALL(observer1, OnBitrateAllocation(kRemoteSsrc1, bitrate_allocation));
  EXPECT_CALL(observer2, OnBitrateAllocation(_, _)).Times(0);
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));
}

TEST_F(RtcpTransceiverImplTest, SkipsIncorrectTargetBitrateEntries) {
  const uint32_t kRemoteSsrc = 12345;
  MockMediaReceiverRtcpObserver observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, &observer);

  webrtc::rtcp::TargetBitrate target_bitrate;
  target_bitrate.AddTargetBitrate(0, 0, /*target_bitrate_kbps=*/10);
  target_bitrate.AddTargetBitrate(0, webrtc::kMaxTemporalStreams, 20);
  target_bitrate.AddTargetBitrate(webrtc::kMaxSpatialLayers, 0, 40);

  webrtc::rtcp::ExtendedReports xr;
  xr.SetTargetBitrate(target_bitrate);
  xr.SetSenderSsrc(kRemoteSsrc);
  auto raw_packet = xr.Build();

  VideoBitrateAllocation expected_allocation;
  expected_allocation.SetBitrate(0, 0, /*bitrate_bps=*/10000);
  EXPECT_CALL(observer, OnBitrateAllocation(kRemoteSsrc, expected_allocation));
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));
}

TEST_F(RtcpTransceiverImplTest, CallsObserverOnByeBehindSenderReport) {
  const uint32_t kRemoteSsrc = 12345;
  MockMediaReceiverRtcpObserver observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, &observer);

  CompoundPacket compound;
  auto sr = std::make_unique<SenderReport>();
  sr->SetSenderSsrc(kRemoteSsrc);
  compound.Append(std::move(sr));
  auto bye = std::make_unique<Bye>();
  bye->SetSenderSsrc(kRemoteSsrc);
  compound.Append(std::move(bye));
  auto raw_packet = compound.Build();

  EXPECT_CALL(observer, OnBye(kRemoteSsrc));
  EXPECT_CALL(observer, OnSenderReport(kRemoteSsrc, _, _));
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));
}

TEST_F(RtcpTransceiverImplTest, CallsObserverOnByeBehindUnknownRtcpPacket) {
  const uint32_t kRemoteSsrc = 12345;
  MockMediaReceiverRtcpObserver observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, &observer);

  CompoundPacket compound;
  // Use Application-Defined rtcp packet as unknown.
  auto app = std::make_unique<webrtc::rtcp::App>();
  compound.Append(std::move(app));
  auto bye = std::make_unique<Bye>();
  bye->SetSenderSsrc(kRemoteSsrc);
  compound.Append(std::move(bye));
  auto raw_packet = compound.Build();

  EXPECT_CALL(observer, OnBye(kRemoteSsrc));
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));
}

TEST_F(RtcpTransceiverImplTest,
       WhenSendsReceiverReportSetsLastSenderReportTimestampPerRemoteSsrc) {
  const uint32_t kRemoteSsrc1 = 4321;
  const uint32_t kRemoteSsrc2 = 5321;
  std::vector<ReportBlock> statistics_report_blocks(2);
  statistics_report_blocks[0].SetMediaSsrc(kRemoteSsrc1);
  statistics_report_blocks[1].SetMediaSsrc(kRemoteSsrc2);
  MockReceiveStatisticsProvider receive_statistics;
  EXPECT_CALL(receive_statistics, RtcpReportBlocks(_))
      .WillOnce(Return(statistics_report_blocks));

  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

  const NtpTime kRemoteNtp(0x9876543211);
  // Receive SenderReport for RemoteSsrc1, but no report for RemoteSsrc2.
  SenderReport sr;
  sr.SetSenderSsrc(kRemoteSsrc1);
  sr.SetNtp(kRemoteNtp);
  auto raw_packet = sr.Build();
  rtcp_transceiver.ReceivePacket(raw_packet, Timestamp::Micros(0));

  // Trigger sending ReceiverReport.
  rtcp_transceiver.SendCompoundPacket();

  EXPECT_GT(rtcp_parser.receiver_report()->num_packets(), 0);
  const auto& report_blocks = rtcp_parser.receiver_report()->report_blocks();
  ASSERT_EQ(report_blocks.size(), 2u);
  // RtcpTransceiverImpl doesn't guarantee order of the report blocks
  // match result of ReceiveStatisticsProvider::RtcpReportBlocks callback,
  // but for simplicity of the test asume it is the same.
  ASSERT_EQ(report_blocks[0].source_ssrc(), kRemoteSsrc1);
  EXPECT_EQ(report_blocks[0].last_sr(), CompactNtp(kRemoteNtp));

  ASSERT_EQ(report_blocks[1].source_ssrc(), kRemoteSsrc2);
  // No matching Sender Report for kRemoteSsrc2, LastSR fields has to be 0.
  EXPECT_EQ(report_blocks[1].last_sr(), 0u);
}

TEST_F(RtcpTransceiverImplTest,
       WhenSendsReceiverReportCalculatesDelaySinceLastSenderReport) {
  const uint32_t kRemoteSsrc1 = 4321;
  const uint32_t kRemoteSsrc2 = 5321;

  std::vector<ReportBlock> statistics_report_blocks(2);
  statistics_report_blocks[0].SetMediaSsrc(kRemoteSsrc1);
  statistics_report_blocks[1].SetMediaSsrc(kRemoteSsrc2);
  MockReceiveStatisticsProvider receive_statistics;
  EXPECT_CALL(receive_statistics, RtcpReportBlocks(_))
      .WillOnce(Return(statistics_report_blocks));

  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

  auto receive_sender_report = [&](uint32_t remote_ssrc) {
    SenderReport sr;
    sr.SetSenderSsrc(remote_ssrc);
    rtcp_transceiver.ReceivePacket(sr.Build(), CurrentTime());
  };

  receive_sender_report(kRemoteSsrc1);
  time_controller().AdvanceTime(TimeDelta::Millis(100));

  receive_sender_report(kRemoteSsrc2);
  time_controller().AdvanceTime(TimeDelta::Millis(100));

  // Trigger ReceiverReport back.
  rtcp_transceiver.SendCompoundPacket();

  EXPECT_GT(rtcp_parser.receiver_report()->num_packets(), 0);
  const auto& report_blocks = rtcp_parser.receiver_report()->report_blocks();
  ASSERT_EQ(report_blocks.size(), 2u);
  // RtcpTransceiverImpl doesn't guarantee order of the report blocks
  // match result of ReceiveStatisticsProvider::RtcpReportBlocks callback,
  // but for simplicity of the test asume it is the same.
  ASSERT_EQ(report_blocks[0].source_ssrc(), kRemoteSsrc1);
  EXPECT_THAT(CompactNtpRttToTimeDelta(report_blocks[0].delay_since_last_sr()),
              Near(TimeDelta::Millis(200)));

  ASSERT_EQ(report_blocks[1].source_ssrc(), kRemoteSsrc2);
  EXPECT_THAT(CompactNtpRttToTimeDelta(report_blocks[1].delay_since_last_sr()),
              Near(TimeDelta::Millis(100)));
}

TEST_F(RtcpTransceiverImplTest, MaySendMultipleReceiverReportInSinglePacket) {
  std::vector<ReportBlock> statistics_report_blocks(40);
  MockReceiveStatisticsProvider receive_statistics;
  EXPECT_CALL(receive_statistics, RtcpReportBlocks(/*max_blocks=*/Ge(40u)))
      .WillOnce(Return(statistics_report_blocks));

  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

  // Trigger ReceiverReports.
  rtcp_transceiver.SendCompoundPacket();

  // Expect a single RTCP packet with multiple receiver reports in it.
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  // Receiver report may contain up to 31 report blocks, thus 2 reports are
  // needed to carry 40 blocks: 31 in the first, 9 in the last.
  EXPECT_EQ(rtcp_parser.receiver_report()->num_packets(), 2);
  // RtcpParser remembers just the last receiver report, thus can't check number
  // of blocks in the first receiver report.
  EXPECT_THAT(rtcp_parser.receiver_report()->report_blocks(), SizeIs(9));
}

TEST_F(RtcpTransceiverImplTest, AttachMaxNumberOfReportBlocksToCompoundPacket) {
  MockReceiveStatisticsProvider receive_statistics;
  EXPECT_CALL(receive_statistics, RtcpReportBlocks)
      .WillOnce([](size_t max_blocks) {
        return std::vector<ReportBlock>(max_blocks);
      });
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.rtcp_mode = RtcpMode::kCompound;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{0});
  // Send some fast feedback message. Because of compound mode, report blocks
  // should be attached.
  rtcp_transceiver.SendPictureLossIndication(/*ssrc=*/123);

  // Expect single RTCP packet with multiple receiver reports and a PLI.
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  EXPECT_GT(rtcp_parser.receiver_report()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.pli()->num_packets(), 1);
}

TEST_F(RtcpTransceiverImplTest, SendsNack) {
  const uint32_t kSenderSsrc = 1234;
  const uint32_t kRemoteSsrc = 4321;
  std::vector<uint16_t> kMissingSequenceNumbers = {34, 37, 38};
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendNack(kRemoteSsrc, kMissingSequenceNumbers);

  EXPECT_EQ(rtcp_parser.nack()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.nack()->sender_ssrc(), kSenderSsrc);
  EXPECT_EQ(rtcp_parser.nack()->media_ssrc(), kRemoteSsrc);
  EXPECT_EQ(rtcp_parser.nack()->packet_ids(), kMissingSequenceNumbers);
}

TEST_F(RtcpTransceiverImplTest, ReceivesNack) {
  static constexpr uint32_t kRemoteSsrc = 4321;
  static constexpr uint32_t kMediaSsrc1 = 1234;
  static constexpr uint32_t kMediaSsrc2 = 1235;
  std::vector<uint16_t> kMissingSequenceNumbers = {34, 37, 38};
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler local_stream1;
  MockRtpStreamRtcpHandler local_stream2;
  EXPECT_CALL(local_stream1,
              OnNack(kRemoteSsrc, ElementsAreArray(kMissingSequenceNumbers)));
  EXPECT_CALL(local_stream2, OnNack).Times(0);

  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc1, &local_stream1));
  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc2, &local_stream2));

  rtcp::Nack nack;
  nack.SetSenderSsrc(kRemoteSsrc);
  nack.SetMediaSsrc(kMediaSsrc1);
  nack.SetPacketIds(kMissingSequenceNumbers);
  rtcp_transceiver.ReceivePacket(nack.Build(), config.clock->CurrentTime());
}

TEST_F(RtcpTransceiverImplTest, RequestKeyFrameWithPictureLossIndication) {
  const uint32_t kSenderSsrc = 1234;
  const uint32_t kRemoteSsrc = 4321;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendPictureLossIndication(kRemoteSsrc);

  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  EXPECT_EQ(rtcp_parser.pli()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.pli()->sender_ssrc(), kSenderSsrc);
  EXPECT_EQ(rtcp_parser.pli()->media_ssrc(), kRemoteSsrc);
}

TEST_F(RtcpTransceiverImplTest, ReceivesPictureLossIndication) {
  static constexpr uint32_t kRemoteSsrc = 4321;
  static constexpr uint32_t kMediaSsrc1 = 1234;
  static constexpr uint32_t kMediaSsrc2 = 1235;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler local_stream1;
  MockRtpStreamRtcpHandler local_stream2;
  EXPECT_CALL(local_stream1, OnPli(kRemoteSsrc));
  EXPECT_CALL(local_stream2, OnPli).Times(0);

  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc1, &local_stream1));
  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc2, &local_stream2));

  rtcp::Pli pli;
  pli.SetSenderSsrc(kRemoteSsrc);
  pli.SetMediaSsrc(kMediaSsrc1);
  rtcp_transceiver.ReceivePacket(pli.Build(), config.clock->CurrentTime());
}

TEST_F(RtcpTransceiverImplTest, RequestKeyFrameWithFullIntraRequest) {
  const uint32_t kSenderSsrc = 1234;
  const uint32_t kRemoteSsrcs[] = {4321, 5321};
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendFullIntraRequest(kRemoteSsrcs, true);

  EXPECT_EQ(rtcp_parser.fir()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.fir()->sender_ssrc(), kSenderSsrc);
  EXPECT_EQ(rtcp_parser.fir()->requests()[0].ssrc, kRemoteSsrcs[0]);
  EXPECT_EQ(rtcp_parser.fir()->requests()[1].ssrc, kRemoteSsrcs[1]);
}

TEST_F(RtcpTransceiverImplTest, RequestKeyFrameWithFirIncreaseSeqNoPerSsrc) {
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  const uint32_t kBothRemoteSsrcs[] = {4321, 5321};
  const uint32_t kOneRemoteSsrc[] = {4321};

  rtcp_transceiver.SendFullIntraRequest(kBothRemoteSsrcs, true);
  ASSERT_EQ(rtcp_parser.fir()->requests()[0].ssrc, kBothRemoteSsrcs[0]);
  uint8_t fir_sequence_number0 = rtcp_parser.fir()->requests()[0].seq_nr;
  ASSERT_EQ(rtcp_parser.fir()->requests()[1].ssrc, kBothRemoteSsrcs[1]);
  uint8_t fir_sequence_number1 = rtcp_parser.fir()->requests()[1].seq_nr;

  rtcp_transceiver.SendFullIntraRequest(kOneRemoteSsrc, true);
  ASSERT_EQ(rtcp_parser.fir()->requests().size(), 1u);
  ASSERT_EQ(rtcp_parser.fir()->requests()[0].ssrc, kBothRemoteSsrcs[0]);
  EXPECT_EQ(rtcp_parser.fir()->requests()[0].seq_nr, fir_sequence_number0 + 1);

  rtcp_transceiver.SendFullIntraRequest(kBothRemoteSsrcs, true);
  ASSERT_EQ(rtcp_parser.fir()->requests().size(), 2u);
  ASSERT_EQ(rtcp_parser.fir()->requests()[0].ssrc, kBothRemoteSsrcs[0]);
  EXPECT_EQ(rtcp_parser.fir()->requests()[0].seq_nr, fir_sequence_number0 + 2);
  ASSERT_EQ(rtcp_parser.fir()->requests()[1].ssrc, kBothRemoteSsrcs[1]);
  EXPECT_EQ(rtcp_parser.fir()->requests()[1].seq_nr, fir_sequence_number1 + 1);
}

TEST_F(RtcpTransceiverImplTest, SendFirDoesNotIncreaseSeqNoIfOldRequest) {
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  const uint32_t kBothRemoteSsrcs[] = {4321, 5321};

  rtcp_transceiver.SendFullIntraRequest(kBothRemoteSsrcs, true);
  ASSERT_EQ(rtcp_parser.fir()->requests().size(), 2u);
  ASSERT_EQ(rtcp_parser.fir()->requests()[0].ssrc, kBothRemoteSsrcs[0]);
  uint8_t fir_sequence_number0 = rtcp_parser.fir()->requests()[0].seq_nr;
  ASSERT_EQ(rtcp_parser.fir()->requests()[1].ssrc, kBothRemoteSsrcs[1]);
  uint8_t fir_sequence_number1 = rtcp_parser.fir()->requests()[1].seq_nr;

  rtcp_transceiver.SendFullIntraRequest(kBothRemoteSsrcs, false);
  ASSERT_EQ(rtcp_parser.fir()->requests().size(), 2u);
  ASSERT_EQ(rtcp_parser.fir()->requests()[0].ssrc, kBothRemoteSsrcs[0]);
  EXPECT_EQ(rtcp_parser.fir()->requests()[0].seq_nr, fir_sequence_number0);
  ASSERT_EQ(rtcp_parser.fir()->requests()[1].ssrc, kBothRemoteSsrcs[1]);
  EXPECT_EQ(rtcp_parser.fir()->requests()[1].seq_nr, fir_sequence_number1);
}

TEST_F(RtcpTransceiverImplTest, ReceivesFir) {
  static constexpr uint32_t kRemoteSsrc = 4321;
  static constexpr uint32_t kMediaSsrc1 = 1234;
  static constexpr uint32_t kMediaSsrc2 = 1235;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler local_stream1;
  MockRtpStreamRtcpHandler local_stream2;
  EXPECT_CALL(local_stream1, OnFir(kRemoteSsrc));
  EXPECT_CALL(local_stream2, OnFir).Times(0);

  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc1, &local_stream1));
  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc2, &local_stream2));

  rtcp::Fir fir;
  fir.SetSenderSsrc(kRemoteSsrc);
  fir.AddRequestTo(kMediaSsrc1, /*seq_num=*/13);

  rtcp_transceiver.ReceivePacket(fir.Build(), config.clock->CurrentTime());
}

TEST_F(RtcpTransceiverImplTest, IgnoresReceivedFirWithRepeatedSequenceNumber) {
  static constexpr uint32_t kRemoteSsrc = 4321;
  static constexpr uint32_t kMediaSsrc1 = 1234;
  static constexpr uint32_t kMediaSsrc2 = 1235;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler local_stream1;
  MockRtpStreamRtcpHandler local_stream2;
  EXPECT_CALL(local_stream1, OnFir(kRemoteSsrc)).Times(1);
  EXPECT_CALL(local_stream2, OnFir(kRemoteSsrc)).Times(2);

  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc1, &local_stream1));
  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc2, &local_stream2));

  rtcp::Fir fir1;
  fir1.SetSenderSsrc(kRemoteSsrc);
  fir1.AddRequestTo(kMediaSsrc1, /*seq_num=*/132);
  fir1.AddRequestTo(kMediaSsrc2, /*seq_num=*/10);
  rtcp_transceiver.ReceivePacket(fir1.Build(), config.clock->CurrentTime());

  // Repeat request for MediaSsrc1 - expect it to be ignored,
  // Change FIR sequence number for MediaSsrc2 - expect a 2nd callback.
  rtcp::Fir fir2;
  fir2.SetSenderSsrc(kRemoteSsrc);
  fir2.AddRequestTo(kMediaSsrc1, /*seq_num=*/132);
  fir2.AddRequestTo(kMediaSsrc2, /*seq_num=*/13);
  rtcp_transceiver.ReceivePacket(fir2.Build(), config.clock->CurrentTime());
}

TEST_F(RtcpTransceiverImplTest, ReceivedFirTracksSequenceNumberPerRemoteSsrc) {
  static constexpr uint32_t kRemoteSsrc1 = 4321;
  static constexpr uint32_t kRemoteSsrc2 = 4323;
  static constexpr uint32_t kMediaSsrc = 1234;
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler local_stream;
  EXPECT_CALL(local_stream, OnFir(kRemoteSsrc1));
  EXPECT_CALL(local_stream, OnFir(kRemoteSsrc2));

  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc, &local_stream));

  rtcp::Fir fir1;
  fir1.SetSenderSsrc(kRemoteSsrc1);
  fir1.AddRequestTo(kMediaSsrc, /*seq_num=*/13);
  rtcp_transceiver.ReceivePacket(fir1.Build(), config.clock->CurrentTime());

  // Use the same FIR sequence number, but different sender SSRC.
  rtcp::Fir fir2;
  fir2.SetSenderSsrc(kRemoteSsrc2);
  fir2.AddRequestTo(kMediaSsrc, /*seq_num=*/13);
  rtcp_transceiver.ReceivePacket(fir2.Build(), config.clock->CurrentTime());
}

TEST_F(RtcpTransceiverImplTest, KeyFrameRequestCreatesCompoundPacket) {
  const uint32_t kRemoteSsrcs[] = {4321};
  RtcpTransceiverConfig config = DefaultTestConfig();
  // Turn periodic off to ensure sent rtcp packet is explicitly requested.
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);

  config.rtcp_mode = webrtc::RtcpMode::kCompound;

  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.SendFullIntraRequest(kRemoteSsrcs, true);

  // Test sent packet is compound by expecting presense of receiver report.
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  EXPECT_EQ(rtcp_parser.receiver_report()->num_packets(), 1);
}

TEST_F(RtcpTransceiverImplTest, KeyFrameRequestCreatesReducedSizePacket) {
  const uint32_t kRemoteSsrcs[] = {4321};
  RtcpTransceiverConfig config = DefaultTestConfig();
  // Turn periodic off to ensure sent rtcp packet is explicitly requested.
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);

  config.rtcp_mode = webrtc::RtcpMode::kReducedSize;

  RtcpTransceiverImpl rtcp_transceiver(config);
  rtcp_transceiver.SendFullIntraRequest(kRemoteSsrcs, true);

  // Test sent packet is reduced size by expecting absense of receiver report.
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  EXPECT_EQ(rtcp_parser.receiver_report()->num_packets(), 0);
}

TEST_F(RtcpTransceiverImplTest, SendsXrRrtrWhenEnabled) {
  const uint32_t kSenderSsrc = 4321;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.non_sender_rtt_measurement = true;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();
  NtpTime ntp_time_now = config.clock->CurrentNtpTime();

  EXPECT_EQ(rtcp_parser.xr()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.xr()->sender_ssrc(), kSenderSsrc);
  ASSERT_TRUE(rtcp_parser.xr()->rrtr());
  EXPECT_EQ(rtcp_parser.xr()->rrtr()->ntp(), ntp_time_now);
}

TEST_F(RtcpTransceiverImplTest, RepliesToRrtrWhenEnabled) {
  static constexpr uint32_t kSenderSsrc[] = {4321, 9876};
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.reply_to_non_sender_rtt_measurement = true;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp::ExtendedReports xr;
  rtcp::Rrtr rrtr;
  rrtr.SetNtp(NtpTime(uint64_t{0x1111'2222'3333'4444}));
  xr.SetRrtr(rrtr);
  xr.SetSenderSsrc(kSenderSsrc[0]);
  rtcp_transceiver.ReceivePacket(xr.Build(), CurrentTime());
  AdvanceTime(TimeDelta::Millis(1'500));

  rrtr.SetNtp(NtpTime(uint64_t{0x4444'5555'6666'7777}));
  xr.SetRrtr(rrtr);
  xr.SetSenderSsrc(kSenderSsrc[1]);
  rtcp_transceiver.ReceivePacket(xr.Build(), CurrentTime());
  AdvanceTime(TimeDelta::Millis(500));

  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.xr()->num_packets(), 1);
  static constexpr uint32_t kComactNtpOneSecond = 0x0001'0000;
  EXPECT_THAT(rtcp_parser.xr()->dlrr().sub_blocks(),
              UnorderedElementsAre(
                  rtcp::ReceiveTimeInfo(kSenderSsrc[0], 0x2222'3333,
                                        /*delay=*/2 * kComactNtpOneSecond),
                  rtcp::ReceiveTimeInfo(kSenderSsrc[1], 0x5555'6666,
                                        /*delay=*/kComactNtpOneSecond / 2)));
}

TEST_F(RtcpTransceiverImplTest, CanReplyToRrtrOnceForAllLocalSsrcs) {
  static constexpr uint32_t kRemoteSsrc = 4321;
  static constexpr uint32_t kLocalSsrcs[] = {1234, 5678};
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.reply_to_non_sender_rtt_measurement = true;
  config.reply_to_non_sender_rtt_mesaurments_on_all_ssrcs = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler local_sender0;
  MockRtpStreamRtcpHandler local_sender1;
  rtcp_transceiver.AddMediaSender(kLocalSsrcs[0], &local_sender0);
  rtcp_transceiver.AddMediaSender(kLocalSsrcs[1], &local_sender1);

  rtcp::ExtendedReports xr;
  rtcp::Rrtr rrtr;
  rrtr.SetNtp(NtpTime(uint64_t{0x1111'2222'3333'4444}));
  xr.SetRrtr(rrtr);
  xr.SetSenderSsrc(kRemoteSsrc);
  rtcp_transceiver.ReceivePacket(xr.Build(), CurrentTime());
  AdvanceTime(TimeDelta::Millis(1'500));

  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.xr()->num_packets(), 1);
}

TEST_F(RtcpTransceiverImplTest, CanReplyToRrtrForEachLocalSsrc) {
  static constexpr uint32_t kRemoteSsrc = 4321;
  static constexpr uint32_t kLocalSsrc[] = {1234, 5678};
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.reply_to_non_sender_rtt_measurement = true;
  config.reply_to_non_sender_rtt_mesaurments_on_all_ssrcs = true;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler local_sender0;
  MockRtpStreamRtcpHandler local_sender1;
  rtcp_transceiver.AddMediaSender(kLocalSsrc[0], &local_sender0);
  rtcp_transceiver.AddMediaSender(kLocalSsrc[1], &local_sender1);

  rtcp::ExtendedReports xr;
  rtcp::Rrtr rrtr;
  rrtr.SetNtp(NtpTime(uint64_t{0x1111'2222'3333'4444}));
  xr.SetRrtr(rrtr);
  xr.SetSenderSsrc(kRemoteSsrc);
  rtcp_transceiver.ReceivePacket(xr.Build(), CurrentTime());
  AdvanceTime(TimeDelta::Millis(1'500));

  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.xr()->num_packets(), 2);
}

TEST_F(RtcpTransceiverImplTest, SendsNoXrRrtrWhenDisabled) {
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.non_sender_rtt_measurement = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  // Extended reports rtcp packet might be included for another reason,
  // but it shouldn't contain rrtr block.
  EXPECT_FALSE(rtcp_parser.xr()->rrtr());
}

TEST_F(RtcpTransceiverImplTest, PassRttFromDlrrToLinkObserver) {
  const uint32_t kSenderSsrc = 4321;
  MockNetworkLinkRtcpObserver link_observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  config.network_link_observer = &link_observer;
  config.non_sender_rtt_measurement = true;
  RtcpTransceiverImpl rtcp_transceiver(config);

  Timestamp send_time = Timestamp::Seconds(5678);
  Timestamp receive_time = send_time + TimeDelta::Millis(110);
  rtcp::ReceiveTimeInfo rti;
  rti.ssrc = kSenderSsrc;
  rti.last_rr = CompactNtp(config.clock->ConvertTimestampToNtpTime(send_time));
  rti.delay_since_last_rr = SaturatedToCompactNtp(TimeDelta::Millis(10));
  rtcp::ExtendedReports xr;
  xr.AddDlrrItem(rti);

  EXPECT_CALL(link_observer,
              OnRttUpdate(receive_time, Near(TimeDelta::Millis(100))));
  rtcp_transceiver.ReceivePacket(xr.Build(), receive_time);
}

TEST_F(RtcpTransceiverImplTest, CalculatesRoundTripTimeFromReportBlocks) {
  MockNetworkLinkRtcpObserver link_observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.network_link_observer = &link_observer;
  RtcpTransceiverImpl rtcp_transceiver(config);

  TimeDelta rtt = TimeDelta::Millis(100);
  Timestamp send_time = Timestamp::Seconds(5678);
  Timestamp receive_time = send_time + TimeDelta::Millis(110);
  rtcp::ReceiverReport rr;
  rtcp::ReportBlock rb1;
  rb1.SetLastSr(CompactNtp(config.clock->ConvertTimestampToNtpTime(
      receive_time - rtt - TimeDelta::Millis(10))));
  rb1.SetDelayLastSr(SaturatedToCompactNtp(TimeDelta::Millis(10)));
  rr.AddReportBlock(rb1);
  rtcp::ReportBlock rb2;
  rb2.SetLastSr(CompactNtp(config.clock->ConvertTimestampToNtpTime(
      receive_time - rtt - TimeDelta::Millis(20))));
  rb2.SetDelayLastSr(SaturatedToCompactNtp(TimeDelta::Millis(20)));
  rr.AddReportBlock(rb2);

  EXPECT_CALL(link_observer, OnRttUpdate(receive_time, Near(rtt)));
  rtcp_transceiver.ReceivePacket(rr.Build(), receive_time);
}

TEST_F(RtcpTransceiverImplTest, IgnoresUnknownSsrcInDlrr) {
  const uint32_t kSenderSsrc = 4321;
  const uint32_t kUnknownSsrc = 4322;
  MockNetworkLinkRtcpObserver link_observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  config.non_sender_rtt_measurement = true;
  config.network_link_observer = &link_observer;
  RtcpTransceiverImpl rtcp_transceiver(config);

  Timestamp time = Timestamp::Micros(12345678);
  webrtc::rtcp::ReceiveTimeInfo rti;
  rti.ssrc = kUnknownSsrc;
  rti.last_rr = CompactNtp(config.clock->ConvertTimestampToNtpTime(time));
  webrtc::rtcp::ExtendedReports xr;
  xr.AddDlrrItem(rti);
  auto raw_packet = xr.Build();

  EXPECT_CALL(link_observer, OnRttUpdate).Times(0);
  rtcp_transceiver.ReceivePacket(raw_packet, time + TimeDelta::Millis(100));
}

TEST_F(RtcpTransceiverImplTest, ParsesTransportFeedback) {
  MockNetworkLinkRtcpObserver link_observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.network_link_observer = &link_observer;
  Timestamp receive_time = Timestamp::Seconds(5678);
  RtcpTransceiverImpl rtcp_transceiver(config);

  EXPECT_CALL(link_observer, OnTransportFeedback(receive_time, _))
      .WillOnce(WithArg<1>([](const rtcp::TransportFeedback& message) {
        EXPECT_EQ(message.GetBaseSequence(), 321);
        EXPECT_THAT(message.GetReceivedPackets(), SizeIs(2));
      }));

  rtcp::TransportFeedback tb;
  tb.SetBase(/*base_sequence=*/321, Timestamp::Micros(15));
  tb.AddReceivedPacket(/*base_sequence=*/321, Timestamp::Micros(15));
  tb.AddReceivedPacket(/*base_sequence=*/322, Timestamp::Micros(17));
  rtcp_transceiver.ReceivePacket(tb.Build(), receive_time);
}

TEST_F(RtcpTransceiverImplTest, ParsesRemb) {
  MockNetworkLinkRtcpObserver link_observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.network_link_observer = &link_observer;
  Timestamp receive_time = Timestamp::Seconds(5678);
  RtcpTransceiverImpl rtcp_transceiver(config);

  EXPECT_CALL(link_observer,
              OnReceiverEstimatedMaxBitrate(receive_time,
                                            DataRate::BitsPerSec(1'234'000)));

  rtcp::Remb remb;
  remb.SetBitrateBps(1'234'000);
  rtcp_transceiver.ReceivePacket(remb.Build(), receive_time);
}

TEST_F(RtcpTransceiverImplTest,
       CombinesReportBlocksFromSenderAndRecieverReports) {
  MockNetworkLinkRtcpObserver link_observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.network_link_observer = &link_observer;
  Timestamp receive_time = Timestamp::Seconds(5678);
  RtcpTransceiverImpl rtcp_transceiver(config);

  // Assemble compound packet with multiple rtcp packets in it.
  rtcp::CompoundPacket packet;
  auto sr = std::make_unique<rtcp::SenderReport>();
  sr->SetSenderSsrc(1234);
  sr->SetReportBlocks(std::vector<ReportBlock>(31));
  packet.Append(std::move(sr));
  auto rr1 = std::make_unique<rtcp::ReceiverReport>();
  rr1->SetReportBlocks(std::vector<ReportBlock>(31));
  packet.Append(std::move(rr1));
  auto rr2 = std::make_unique<rtcp::ReceiverReport>();
  rr2->SetReportBlocks(std::vector<ReportBlock>(2));
  packet.Append(std::move(rr2));

  EXPECT_CALL(link_observer, OnReport(receive_time, SizeIs(64)));

  rtcp_transceiver.ReceivePacket(packet.Build(), receive_time);
}

TEST_F(RtcpTransceiverImplTest,
       CallbackOnReportBlocksFromSenderAndReceiverReports) {
  static constexpr uint32_t kRemoteSsrc = 5678;
  // Has registered sender, report block attached to sender report.
  static constexpr uint32_t kMediaSsrc1 = 1234;
  // No registered sender, report block attached to receiver report.
  // Such report block shouldn't prevent handling following report block.
  static constexpr uint32_t kMediaSsrc2 = 1235;
  // Has registered sender, no report block attached.
  static constexpr uint32_t kMediaSsrc3 = 1236;
  // Has registered sender, report block attached to receiver report.
  static constexpr uint32_t kMediaSsrc4 = 1237;

  MockNetworkLinkRtcpObserver link_observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  Timestamp receive_time = Timestamp::Seconds(5678);
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler local_stream1;
  MockRtpStreamRtcpHandler local_stream3;
  MockRtpStreamRtcpHandler local_stream4;
  EXPECT_CALL(local_stream1,
              OnReport(Property(&ReportBlockData::sender_ssrc, kRemoteSsrc)));
  EXPECT_CALL(local_stream3, OnReport).Times(0);
  EXPECT_CALL(local_stream4,
              OnReport(Property(&ReportBlockData::sender_ssrc, kRemoteSsrc)));

  ASSERT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc1, &local_stream1));
  ASSERT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc3, &local_stream3));
  ASSERT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc4, &local_stream4));

  // Assemble compound packet with multiple RTCP packets in it.
  rtcp::CompoundPacket packet;
  auto sr = std::make_unique<rtcp::SenderReport>();
  sr->SetSenderSsrc(kRemoteSsrc);
  std::vector<ReportBlock> rb(1);
  rb[0].SetMediaSsrc(kMediaSsrc1);
  sr->SetReportBlocks(std::move(rb));
  packet.Append(std::move(sr));
  auto rr = std::make_unique<rtcp::ReceiverReport>();
  rr->SetSenderSsrc(kRemoteSsrc);
  rb = std::vector<ReportBlock>(2);
  rb[0].SetMediaSsrc(kMediaSsrc2);
  rb[1].SetMediaSsrc(kMediaSsrc4);
  rr->SetReportBlocks(std::move(rb));
  packet.Append(std::move(rr));

  rtcp_transceiver.ReceivePacket(packet.Build(), receive_time);
}

TEST_F(RtcpTransceiverImplTest, FailsToRegisterTwoSendersWithTheSameSsrc) {
  RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
  MockRtpStreamRtcpHandler sender1;
  MockRtpStreamRtcpHandler sender2;

  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(/*local_ssrc=*/10001, &sender1));
  EXPECT_FALSE(rtcp_transceiver.AddMediaSender(/*local_ssrc=*/10001, &sender2));
  EXPECT_TRUE(rtcp_transceiver.AddMediaSender(/*local_ssrc=*/10002, &sender2));

  EXPECT_TRUE(rtcp_transceiver.RemoveMediaSender(/*local_ssrc=*/10001));
  EXPECT_FALSE(rtcp_transceiver.RemoveMediaSender(/*local_ssrc=*/10001));
}

TEST_F(RtcpTransceiverImplTest, SendsSenderReport) {
  static constexpr uint32_t kFeedbackSsrc = 123;
  static constexpr uint32_t kSenderSsrc = 12345;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.feedback_ssrc = kFeedbackSsrc;
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  RtpStreamRtcpHandler::RtpStats sender_stats;
  sender_stats.set_num_sent_packets(10);
  sender_stats.set_num_sent_bytes(1000);
  sender_stats.set_last_rtp_timestamp(0x3333);
  sender_stats.set_last_capture_time(CurrentTime() - TimeDelta::Seconds(2));
  sender_stats.set_last_clock_rate(0x1000);
  MockRtpStreamRtcpHandler sender;
  ON_CALL(sender, SentStats).WillByDefault(Return(sender_stats));
  rtcp_transceiver.AddMediaSender(kSenderSsrc, &sender);

  rtcp_transceiver.SendCompoundPacket();

  ASSERT_GT(rtcp_parser.sender_report()->num_packets(), 0);
  EXPECT_EQ(rtcp_parser.sender_report()->sender_ssrc(), kSenderSsrc);
  EXPECT_EQ(rtcp_parser.sender_report()->ntp(),
            time_controller().GetClock()->CurrentNtpTime());
  EXPECT_EQ(rtcp_parser.sender_report()->rtp_timestamp(), 0x3333u + 0x2000u);
  EXPECT_EQ(rtcp_parser.sender_report()->sender_packet_count(), 10u);
  EXPECT_EQ(rtcp_parser.sender_report()->sender_octet_count(), 1000u);
}

TEST_F(RtcpTransceiverImplTest,
       MaySendBothSenderReportAndReceiverReportInTheSamePacket) {
  RtcpPacketParser rtcp_parser;
  std::vector<ReportBlock> statistics_report_blocks(40);
  MockReceiveStatisticsProvider receive_statistics;
  EXPECT_CALL(receive_statistics, RtcpReportBlocks(/*max_blocks=*/Ge(40u)))
      .WillOnce(Return(statistics_report_blocks));
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

  MockRtpStreamRtcpHandler sender;
  rtcp_transceiver.AddMediaSender(/*ssrc=*/12345, &sender);

  rtcp_transceiver.SendCompoundPacket();

  // Expect a single RTCP packet with a sender and a receiver reports in it.
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  ASSERT_EQ(rtcp_parser.sender_report()->num_packets(), 1);
  ASSERT_EQ(rtcp_parser.receiver_report()->num_packets(), 1);
  // Sender report may contain up to 31 report blocks, thus remaining 9 report
  // block should be attached to the receiver report.
  EXPECT_THAT(rtcp_parser.sender_report()->report_blocks(), SizeIs(31));
  EXPECT_THAT(rtcp_parser.receiver_report()->report_blocks(), SizeIs(9));
}

TEST_F(RtcpTransceiverImplTest, RotatesSendersWhenAllSenderReportDoNotFit) {
  // Send 6 compound packet, each should contain 5 sender reports,
  // each of 6 senders should be mentioned 5 times.
  static constexpr int kNumSenders = 6;
  static constexpr uint32_t kSenderSsrc[kNumSenders] = {10, 20, 30, 40, 50, 60};
  static constexpr int kSendersPerPacket = 5;
  // RtcpPacketParser remembers only latest block for each type, but this test
  // is about sending multiple sender reports in the same packet, thus need
  // a more advance parser: RtcpTranceiver
  RtcpTransceiverConfig receiver_config = DefaultTestConfig();
  RtcpTransceiverImpl rtcp_receiver(receiver_config);
  // Main expectatation: all senders are spread equally across multiple packets.
  NiceMock<MockMediaReceiverRtcpObserver> receiver[kNumSenders];
  for (int i = 0; i < kNumSenders; ++i) {
    SCOPED_TRACE(i);
    EXPECT_CALL(receiver[i], OnSenderReport(kSenderSsrc[i], _, _))
        .Times(kSendersPerPacket);
    rtcp_receiver.AddMediaReceiverRtcpObserver(kSenderSsrc[i], &receiver[i]);
  }

  MockFunction<void(rtc::ArrayView<const uint8_t>)> transport;
  EXPECT_CALL(transport, Call)
      .Times(kNumSenders)
      .WillRepeatedly([&](rtc::ArrayView<const uint8_t> packet) {
        rtcp_receiver.ReceivePacket(packet, CurrentTime());
        return true;
      });
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.rtcp_transport = transport.AsStdFunction();
  // Limit packet to have space just for kSendersPerPacket sender reports.
  // Sender report without report blocks require 28 bytes.
  config.max_packet_size = kSendersPerPacket * 28;
  RtcpTransceiverImpl rtcp_transceiver(config);
  NiceMock<MockRtpStreamRtcpHandler> sender[kNumSenders];
  for (int i = 0; i < kNumSenders; ++i) {
    rtcp_transceiver.AddMediaSender(kSenderSsrc[i], &sender[i]);
  }

  for (int i = 1; i <= kNumSenders; ++i) {
    SCOPED_TRACE(i);
    rtcp_transceiver.SendCompoundPacket();
  }
}

TEST_F(RtcpTransceiverImplTest, SkipsSenderReportForInactiveSender) {
  static constexpr uint32_t kSenderSsrc[] = {12345, 23456};
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpPacketParser rtcp_parser;
  config.rtcp_transport = RtcpParserTransport(rtcp_parser);
  RtcpTransceiverImpl rtcp_transceiver(config);

  RtpStreamRtcpHandler::RtpStats sender_stats[2];
  NiceMock<MockRtpStreamRtcpHandler> sender[2];
  ON_CALL(sender[0], SentStats).WillByDefault([&] { return sender_stats[0]; });
  ON_CALL(sender[1], SentStats).WillByDefault([&] { return sender_stats[1]; });
  rtcp_transceiver.AddMediaSender(kSenderSsrc[0], &sender[0]);
  rtcp_transceiver.AddMediaSender(kSenderSsrc[1], &sender[1]);

  // Start with both senders beeing active.
  sender_stats[0].set_num_sent_packets(10);
  sender_stats[0].set_num_sent_bytes(1'000);
  sender_stats[1].set_num_sent_packets(5);
  sender_stats[1].set_num_sent_bytes(2'000);
  rtcp_transceiver.SendCompoundPacket();
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{1});
  EXPECT_EQ(rtcp_parser.sender_report()->num_packets(), 2);

  // Keep 1st sender active, but make 2nd second look inactive by returning the
  // same RtpStats.
  sender_stats[0].set_num_sent_packets(15);
  sender_stats[0].set_num_sent_bytes(2'000);
  rtcp_transceiver.SendCompoundPacket();
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{2});
  EXPECT_EQ(rtcp_parser.sender_report()->num_packets(), 3);
  EXPECT_EQ(rtcp_parser.sender_report()->sender_ssrc(), kSenderSsrc[0]);

  // Swap active sender.
  sender_stats[1].set_num_sent_packets(20);
  sender_stats[1].set_num_sent_bytes(3'000);
  rtcp_transceiver.SendCompoundPacket();
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{3});
  EXPECT_EQ(rtcp_parser.sender_report()->num_packets(), 4);
  EXPECT_EQ(rtcp_parser.sender_report()->sender_ssrc(), kSenderSsrc[1]);

  // Activate both senders again.
  sender_stats[0].set_num_sent_packets(20);
  sender_stats[0].set_num_sent_bytes(3'000);
  sender_stats[1].set_num_sent_packets(25);
  sender_stats[1].set_num_sent_bytes(3'500);
  rtcp_transceiver.SendCompoundPacket();
  EXPECT_EQ(rtcp_parser.processed_rtcp_packets(), size_t{4});
  EXPECT_EQ(rtcp_parser.sender_report()->num_packets(), 6);
}

}  // namespace
}  // namespace webrtc
