/*
 *  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 <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <span>
#include <utility>
#include <vector>

#include "api/rtp_headers.h"
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.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 "api/video/video_codec_constants.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/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 "modules/rtp_rtcp/source/rtcp_packet/congestion_control_feedback.h"
#include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "modules/rtp_rtcp/source/rtcp_packet/rrtr.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h"
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "modules/rtp_rtcp/source/rtcp_transceiver_config.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/ntp_time.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/rtcp_packet_parser.h"

namespace webrtc {
namespace {

using rtcp::Bye;
using rtcp::CompoundPacket;
using rtcp::ReportBlock;
using rtcp::SenderReport;
using test::RtcpPacketParser;
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;

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, std::span<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(std::span<const uint8_t>)> AsStdFunction() {
    return [this](std::span<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(std::span<const uint8_t>)> RtcpParserTransport(
    RtcpPacketParser& parser) {
  return [&parser](std::span<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::kNormal);
  }

 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(std::span<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(std::span<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(std::span<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 = 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 = 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 = 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);

  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);
  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);

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

  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<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 = 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 = 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);
  rtcp::ReceiveTimeInfo rti;
  rti.ssrc = kUnknownSsrc;
  rti.last_rr = CompactNtp(config.clock->ConvertTimestampToNtpTime(time));
  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, ParsesCongestionControlFeedback) {
  MockNetworkLinkRtcpObserver link_observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.network_link_observer = &link_observer;
  const uint32_t receive_time_ntp = 5678;
  Timestamp receive_time = Timestamp::Seconds(9843);
  RtcpTransceiverImpl rtcp_transceiver(config);

  EXPECT_CALL(link_observer, OnCongestionControlFeedback(receive_time, _))
      .WillOnce(WithArg<1>([](const rtcp::CongestionControlFeedback& message) {
        EXPECT_EQ(message.report_timestamp_compact_ntp(), 5678u);
        EXPECT_THAT(message.packets(), SizeIs(2));
      }));

  std::vector<rtcp::CongestionControlFeedback::PacketInfo> packets = {
      {.ssrc = 1,
       .sequence_number = 321,
       .arrival_time_offset = TimeDelta::Millis(15)},
      {.ssrc = 1,
       .sequence_number = 322,
       .arrival_time_offset = TimeDelta::Millis(17)}};
  rtcp::CongestionControlFeedback ccfb(std::move(packets), receive_time_ntp);
  rtcp_transceiver.ReceivePacket(ccfb.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(std::span<const uint8_t>)> transport;
  EXPECT_CALL(transport, Call)
      .Times(kNumSenders)
      .WillRepeatedly([&](std::span<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
