/*
 *  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/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/mocks/mock_rtcp_rtt_stats.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/time_util.h"
#include "rtc_base/event.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/clock.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/mock_transport.h"
#include "test/rtcp_packet_parser.h"

namespace webrtc {
namespace {

using ::testing::_;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::Ge;
using ::testing::NiceMock;
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,
              OnReportBlock,
              (uint32_t, const rtcp::ReportBlock&),
              (override));

 private:
  int num_calls_ = 0;
};

class MockNetworkLinkRtcpObserver : public NetworkLinkRtcpObserver {
 public:
  MOCK_METHOD(void,
              OnRttUpdate,
              (Timestamp receive_time, TimeDelta rtt),
              (override));
  MOCK_METHOD(void,
              OnTransportFeedback,
              (Timestamp receive_time, const rtcp::TransportFeedback& feedback),
              (override));
  MOCK_METHOD(void,
              OnReceiverEstimatedMaxBitrate,
              (Timestamp receive_time, DataRate bitrate),
              (override));
  MOCK_METHOD(void,
              OnReportBlocks,
              (Timestamp receive_time,
               rtc::ArrayView<const rtcp::ReportBlock> report_blocks),
              (override));
};

// Since some tests will need to wait for this period, make it small to avoid
// slowing tests too much. As long as there are test bots with high scheduler
// granularity, small period should be ok.
constexpr TimeDelta kReportPeriod = TimeDelta::Millis(10);
// On some systems task queue might be slow, instead of guessing right
// grace period, use very large timeout, 100x larger expected wait time.
// Use finite timeout to fail tests rather than hang them.
constexpr int kAlmostForeverMs = 1000;

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 webrtc::Transport {
 public:
  bool SendRtcp(const uint8_t* data, size_t size) override {
    sent_rtcp_.Set();
    return true;
  }
  bool SendRtp(const uint8_t*, size_t, const webrtc::PacketOptions&) override {
    ADD_FAILURE() << "RtcpTransciver shouldn't send rtp packets.";
    return true;
  }

  // Returns true when packet was received by the transport.
  bool WaitPacket() {
    // Normally packet should be sent fast, long before the timeout.
    bool packet_sent = sent_rtcp_.Wait(kAlmostForeverMs);
    // Disallow tests to wait almost forever for no packets.
    EXPECT_TRUE(packet_sent);
    // Return wait result even though it is expected to be true, so that
    // individual tests can EXPECT on it for better error message.
    return packet_sent;
  }

 private:
  rtc::Event sent_rtcp_;
};

class RtcpParserTransport : public webrtc::Transport {
 public:
  explicit RtcpParserTransport(RtcpPacketParser* parser) : parser_(parser) {}
  // Returns total number of rtcp packet received.
  int num_packets() const { return num_packets_; }

 private:
  bool SendRtcp(const uint8_t* data, size_t size) override {
    ++num_packets_;
    parser_->Parse(data, size);
    return true;
  }

  bool SendRtp(const uint8_t*, size_t, const webrtc::PacketOptions&) override {
    ADD_FAILURE() << "RtcpTransciver shouldn't send rtp packets.";
    return true;
  }

  RtcpPacketParser* const parser_;
  int num_packets_ = 0;
};

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.
  static MockTransport null_transport;
  static SimulatedClock null_clock(0);
  RtcpTransceiverConfig config;
  config.clock = &null_clock;
  config.outgoing_transport = &null_transport;
  config.schedule_periodic_compound_packets = false;
  config.initial_report_delay = TimeDelta::Millis(10);
  config.report_period = kReportPeriod;
  return config;
}

TEST(RtcpTransceiverImplTest, NeedToStopPeriodicTaskToDestroyOnTaskQueue) {
  SimulatedClock clock(0);
  FakeRtcpTransport transport;
  TaskQueueForTest queue("rtcp");
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.task_queue = queue.Get();
  config.schedule_periodic_compound_packets = true;
  config.outgoing_transport = &transport;
  auto* rtcp_transceiver = new RtcpTransceiverImpl(config);
  // Wait for a periodic packet.
  EXPECT_TRUE(transport.WaitPacket());

  rtc::Event done;
  queue.PostTask([rtcp_transceiver, &done] {
    rtcp_transceiver->StopPeriodicTask();
    delete rtcp_transceiver;
    done.Set();
  });
  ASSERT_TRUE(done.Wait(/*milliseconds=*/1000));
}

TEST(RtcpTransceiverImplTest, CanBeDestroyedRightAfterCreation) {
  SimulatedClock clock(0);
  FakeRtcpTransport transport;
  TaskQueueForTest queue("rtcp");
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.task_queue = queue.Get();
  config.schedule_periodic_compound_packets = true;
  config.outgoing_transport = &transport;

  rtc::Event done;
  queue.PostTask([&] {
    RtcpTransceiverImpl rtcp_transceiver(config);
    rtcp_transceiver.StopPeriodicTask();
    done.Set();
  });
  ASSERT_TRUE(done.Wait(/*milliseconds=*/1000));
}

TEST(RtcpTransceiverImplTest, CanDestroyAfterTaskQueue) {
  SimulatedClock clock(0);
  FakeRtcpTransport transport;
  auto* queue = new TaskQueueForTest("rtcp");
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.task_queue = queue->Get();
  config.schedule_periodic_compound_packets = true;
  config.outgoing_transport = &transport;
  auto* rtcp_transceiver = new RtcpTransceiverImpl(config);
  // Wait for a periodic packet.
  EXPECT_TRUE(transport.WaitPacket());

  delete queue;
  delete rtcp_transceiver;
}

TEST(RtcpTransceiverImplTest, DelaysSendingFirstCompondPacket) {
  SimulatedClock clock(0);
  TaskQueueForTest queue("rtcp");
  FakeRtcpTransport transport;
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.outgoing_transport = &transport;
  config.initial_report_delay = TimeDelta::Millis(10);
  config.task_queue = queue.Get();
  absl::optional<RtcpTransceiverImpl> rtcp_transceiver;

  int64_t started_ms = rtc::TimeMillis();
  queue.PostTask([&] { rtcp_transceiver.emplace(config); });
  EXPECT_TRUE(transport.WaitPacket());

  EXPECT_GE(rtc::TimeMillis() - started_ms, config.initial_report_delay.ms());

  // Cleanup.
  rtc::Event done;
  queue.PostTask([&] {
    rtcp_transceiver->StopPeriodicTask();
    rtcp_transceiver.reset();
    done.Set();
  });
  ASSERT_TRUE(done.Wait(kAlmostForeverMs));
}

TEST(RtcpTransceiverImplTest, PeriodicallySendsPackets) {
  SimulatedClock clock(0);
  TaskQueueForTest queue("rtcp");
  FakeRtcpTransport transport;
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.outgoing_transport = &transport;
  config.initial_report_delay = TimeDelta::Zero();
  config.report_period = kReportPeriod;
  config.task_queue = queue.Get();
  absl::optional<RtcpTransceiverImpl> rtcp_transceiver;
  int64_t time_just_before_1st_packet_ms = 0;
  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_ms = rtc::TimeMillis();
    rtcp_transceiver.emplace(config);
  });

  EXPECT_TRUE(transport.WaitPacket());
  EXPECT_TRUE(transport.WaitPacket());
  int64_t time_just_after_2nd_packet_ms = rtc::TimeMillis();

  EXPECT_GE(time_just_after_2nd_packet_ms - time_just_before_1st_packet_ms,
            config.report_period.ms() - 1);

  // Cleanup.
  rtc::Event done;
  queue.PostTask([&] {
    rtcp_transceiver->StopPeriodicTask();
    rtcp_transceiver.reset();
    done.Set();
  });
  ASSERT_TRUE(done.Wait(kAlmostForeverMs));
}

TEST(RtcpTransceiverImplTest, SendCompoundPacketDelaysPeriodicSendPackets) {
  SimulatedClock clock(0);
  TaskQueueForTest queue("rtcp");
  FakeRtcpTransport transport;
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.outgoing_transport = &transport;
  config.initial_report_delay = TimeDelta::Zero();
  config.report_period = kReportPeriod;
  config.task_queue = queue.Get();
  absl::optional<RtcpTransceiverImpl> rtcp_transceiver;
  queue.PostTask([&] { rtcp_transceiver.emplace(config); });

  // Wait for first packet.
  EXPECT_TRUE(transport.WaitPacket());
  // Send non periodic one after half period.
  rtc::Event non_periodic;
  int64_t time_of_non_periodic_packet_ms = 0;
  queue.PostDelayedTask(
      [&] {
        time_of_non_periodic_packet_ms = rtc::TimeMillis();
        rtcp_transceiver->SendCompoundPacket();
        non_periodic.Set();
      },
      (config.report_period / 2).ms());
  // 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(non_periodic.Wait(kAlmostForeverMs));
  EXPECT_TRUE(transport.WaitPacket());
  // Wait for next periodic packet.
  EXPECT_TRUE(transport.WaitPacket());
  int64_t time_of_last_periodic_packet_ms = rtc::TimeMillis();

  EXPECT_GE(time_of_last_periodic_packet_ms - time_of_non_periodic_packet_ms,
            config.report_period.ms() - 1);

  // Cleanup.
  rtc::Event done;
  queue.PostTask([&] {
    rtcp_transceiver->StopPeriodicTask();
    rtcp_transceiver.reset();
    done.Set();
  });
  ASSERT_TRUE(done.Wait(kAlmostForeverMs));
}

TEST(RtcpTransceiverImplTest, SendsNoRtcpWhenNetworkStateIsDown) {
  SimulatedClock clock(0);
  MockTransport mock_transport;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.initial_ready_to_send = false;
  config.outgoing_transport = &mock_transport;
  RtcpTransceiverImpl rtcp_transceiver(config);

  EXPECT_CALL(mock_transport, SendRtcp(_, _)).Times(0);

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

TEST(RtcpTransceiverImplTest, SendsRtcpWhenNetworkStateIsUp) {
  SimulatedClock clock(0);
  MockTransport mock_transport;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.initial_ready_to_send = false;
  config.outgoing_transport = &mock_transport;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SetReadyToSend(true);

  EXPECT_CALL(mock_transport, SendRtcp(_, _)).Times(5);

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

TEST(RtcpTransceiverImplTest, SendsPeriodicRtcpWhenNetworkStateIsUp) {
  SimulatedClock clock(0);
  TaskQueueForTest queue("rtcp");
  FakeRtcpTransport transport;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.schedule_periodic_compound_packets = true;
  config.initial_ready_to_send = false;
  config.outgoing_transport = &transport;
  config.task_queue = queue.Get();
  absl::optional<RtcpTransceiverImpl> rtcp_transceiver;
  rtcp_transceiver.emplace(config);

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

  EXPECT_TRUE(transport.WaitPacket());

  // Cleanup.
  rtc::Event done;
  queue.PostTask([&] {
    rtcp_transceiver->StopPeriodicTask();
    rtcp_transceiver.reset();
    done.Set();
  });
  ASSERT_TRUE(done.Wait(kAlmostForeverMs));
}

TEST(RtcpTransceiverImplTest, SendsMinimalCompoundPacket) {
  const uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  config.cname = "cname";
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(RtcpTransceiverImplTest, AvoidsEmptyPacketsInReducedMode) {
  MockTransport transport;
  EXPECT_CALL(transport, SendRtcp).Times(0);
  NiceMock<MockReceiveStatisticsProvider> receive_statistics;
  SimulatedClock clock(0);

  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.outgoing_transport = &transport;
  config.rtcp_mode = webrtc::RtcpMode::kReducedSize;
  config.schedule_periodic_compound_packets = false;
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();
}

TEST(RtcpTransceiverImplTest, AvoidsEmptyReceiverReportsInReducedMode) {
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  NiceMock<MockReceiveStatisticsProvider> receive_statistics;
  SimulatedClock clock(0);

  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.outgoing_transport = &transport;
  config.rtcp_mode = webrtc::RtcpMode::kReducedSize;
  config.schedule_periodic_compound_packets = false;
  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(RtcpTransceiverImplTest, SendsNoRembInitially) {
  const uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(transport.num_packets(), 1);
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 0);
}

TEST(RtcpTransceiverImplTest, SetRembIncludesRembInNextCompoundPacket) {
  const uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(RtcpTransceiverImplTest, SetRembUpdatesValuesToSend) {
  const uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(RtcpTransceiverImplTest, SetRembSendsImmediatelyIfSendRembOnChange) {
  const uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.send_remb_on_change = true;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(RtcpTransceiverImplTest,
     SetRembSendsImmediatelyIfSendRembOnChangeReducedSize) {
  const uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.send_remb_on_change = true;
  config.rtcp_mode = webrtc::RtcpMode::kReducedSize;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(RtcpTransceiverImplTest, SetRembIncludesRembInAllCompoundPackets) {
  const uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(transport.num_packets(), 2);
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 2);
}

TEST(RtcpTransceiverImplTest, SendsNoRembAfterUnset) {
  const uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  config.schedule_periodic_compound_packets = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

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

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

  EXPECT_EQ(transport.num_packets(), 2);
  EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
}

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

  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(RtcpTransceiverImplTest, MultipleObserversOnSameSsrc) {
  const uint32_t kRemoteSsrc = 12345;
  SimulatedClock clock(0);
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  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(RtcpTransceiverImplTest, DoesntCallsObserverAfterRemoved) {
  const uint32_t kRemoteSsrc = 12345;
  SimulatedClock clock(0);
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  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(RtcpTransceiverImplTest, CallsObserverOnSenderReportBySenderSsrc) {
  const uint32_t kRemoteSsrc1 = 12345;
  const uint32_t kRemoteSsrc2 = 22345;
  SimulatedClock clock(0);
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  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(RtcpTransceiverImplTest, CallsObserverOnByeBySenderSsrc) {
  const uint32_t kRemoteSsrc1 = 12345;
  const uint32_t kRemoteSsrc2 = 22345;
  SimulatedClock clock(0);
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  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(RtcpTransceiverImplTest, CallsObserverOnTargetBitrateBySenderSsrc) {
  const uint32_t kRemoteSsrc1 = 12345;
  const uint32_t kRemoteSsrc2 = 22345;
  SimulatedClock clock(0);
  StrictMock<MockMediaReceiverRtcpObserver> observer1;
  StrictMock<MockMediaReceiverRtcpObserver> observer2;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  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(RtcpTransceiverImplTest, SkipsIncorrectTargetBitrateEntries) {
  const uint32_t kRemoteSsrc = 12345;
  SimulatedClock clock(0);
  MockMediaReceiverRtcpObserver observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  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(RtcpTransceiverImplTest, CallsObserverOnByeBehindSenderReport) {
  const uint32_t kRemoteSsrc = 12345;
  SimulatedClock clock(0);
  MockMediaReceiverRtcpObserver observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  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(RtcpTransceiverImplTest, CallsObserverOnByeBehindUnknownRtcpPacket) {
  const uint32_t kRemoteSsrc = 12345;
  SimulatedClock clock(0);
  MockMediaReceiverRtcpObserver observer;
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  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(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));

  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(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));

  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

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

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

  receive_sender_report(kRemoteSsrc2);
  clock.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(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));

  SimulatedClock clock(0);
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(transport.num_packets(), 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(RtcpTransceiverImplTest, AttachMaxNumberOfReportBlocksToCompoundPacket) {
  MockReceiveStatisticsProvider receive_statistics;
  EXPECT_CALL(receive_statistics, RtcpReportBlocks)
      .WillOnce([](size_t max_blocks) {
        return std::vector<ReportBlock>(max_blocks);
      });
  SimulatedClock clock(0);
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.rtcp_mode = RtcpMode::kCompound;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  config.receive_statistics = &receive_statistics;
  RtcpTransceiverImpl rtcp_transceiver(config);

  EXPECT_EQ(transport.num_packets(), 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(transport.num_packets(), 1);
  EXPECT_GT(rtcp_parser.receiver_report()->num_packets(), 1);
  EXPECT_EQ(rtcp_parser.pli()->num_packets(), 1);
}

TEST(RtcpTransceiverImplTest, SendsNack) {
  const uint32_t kSenderSsrc = 1234;
  const uint32_t kRemoteSsrc = 4321;
  std::vector<uint16_t> kMissingSequenceNumbers = {34, 37, 38};
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(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(RtcpTransceiverImplTest, RequestKeyFrameWithPictureLossIndication) {
  const uint32_t kSenderSsrc = 1234;
  const uint32_t kRemoteSsrc = 4321;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendPictureLossIndication(kRemoteSsrc);

  EXPECT_EQ(transport.num_packets(), 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(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(RtcpTransceiverImplTest, RequestKeyFrameWithFullIntraRequest) {
  const uint32_t kSenderSsrc = 1234;
  const uint32_t kRemoteSsrcs[] = {4321, 5321};
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(RtcpTransceiverImplTest, RequestKeyFrameWithFirIncreaseSeqNoPerSsrc) {
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(RtcpTransceiverImplTest, SendFirDoesNotIncreaseSeqNoIfOldRequest) {
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(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(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(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(RtcpTransceiverImplTest, KeyFrameRequestCreatesCompoundPacket) {
  const uint32_t kRemoteSsrcs[] = {4321};
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  // Turn periodic off to ensure sent rtcp packet is explicitly requested.
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;

  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(transport.num_packets(), 1);
  EXPECT_EQ(rtcp_parser.receiver_report()->num_packets(), 1);
}

TEST(RtcpTransceiverImplTest, KeyFrameRequestCreatesReducedSizePacket) {
  const uint32_t kRemoteSsrcs[] = {4321};
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  // Turn periodic off to ensure sent rtcp packet is explicitly requested.
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;

  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(transport.num_packets(), 1);
  EXPECT_EQ(rtcp_parser.receiver_report()->num_packets(), 0);
}

TEST(RtcpTransceiverImplTest, SendsXrRrtrWhenEnabled) {
  const uint32_t kSenderSsrc = 4321;
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  config.non_sender_rtt_measurement = true;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();
  NtpTime ntp_time_now = 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(RtcpTransceiverImplTest, RepliesToRrtrWhenEnabled) {
  static constexpr uint32_t kSenderSsrc[] = {4321, 9876};
  SimulatedClock clock(0);
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.reply_to_non_sender_rtt_measurement = true;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(), clock.CurrentTime());
  clock.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(), clock.CurrentTime());
  clock.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(RtcpTransceiverImplTest, CanReplyToRrtrOnceForAllLocalSsrcs) {
  static constexpr uint32_t kRemoteSsrc = 4321;
  static constexpr uint32_t kLocalSsrcs[] = {1234, 5678};
  SimulatedClock clock(0);
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.reply_to_non_sender_rtt_measurement = true;
  config.reply_to_non_sender_rtt_mesaurments_on_all_ssrcs = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(), clock.CurrentTime());
  clock.AdvanceTime(TimeDelta::Millis(1'500));

  rtcp_transceiver.SendCompoundPacket();

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

TEST(RtcpTransceiverImplTest, CanReplyToRrtrForEachLocalSsrc) {
  static constexpr uint32_t kRemoteSsrc = 4321;
  static constexpr uint32_t kLocalSsrc[] = {1234, 5678};
  SimulatedClock clock(0);
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.reply_to_non_sender_rtt_measurement = true;
  config.reply_to_non_sender_rtt_mesaurments_on_all_ssrcs = true;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(), clock.CurrentTime());
  clock.AdvanceTime(TimeDelta::Millis(1'500));

  rtcp_transceiver.SendCompoundPacket();

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

TEST(RtcpTransceiverImplTest, SendsNoXrRrtrWhenDisabled) {
  SimulatedClock clock(0);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.schedule_periodic_compound_packets = false;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  config.non_sender_rtt_measurement = false;
  RtcpTransceiverImpl rtcp_transceiver(config);

  rtcp_transceiver.SendCompoundPacket();

  EXPECT_EQ(transport.num_packets(), 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(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(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(RtcpTransceiverImplTest, IgnoresUnknownSsrcInDlrr) {
  const uint32_t kSenderSsrc = 4321;
  const uint32_t kUnknownSsrc = 4322;
  SimulatedClock clock(0);
  MockNetworkLinkRtcpObserver link_observer;
  MockTransport null_transport;
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kSenderSsrc;
  config.schedule_periodic_compound_packets = false;
  config.outgoing_transport = &null_transport;
  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(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(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, /*ref_timestamp_us=*/15);
  tb.AddReceivedPacket(/*base_sequence=*/321, /*timestamp_us=*/15);
  tb.AddReceivedPacket(/*base_sequence=*/322, /*timestamp_us=*/17);
  rtcp_transceiver.ReceivePacket(tb.Build(), receive_time);
}

TEST(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(RtcpTransceiverImplTest,
     CombinesReportBlocksFromSenderAndReceiverReports) {
  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, OnReportBlocks(receive_time, SizeIs(64)));

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

TEST(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, OnReportBlock(kRemoteSsrc, _));
  EXPECT_CALL(local_stream3, OnReportBlock).Times(0);
  EXPECT_CALL(local_stream4, OnReportBlock(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(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(RtcpTransceiverImplTest, SendsSenderReport) {
  static constexpr uint32_t kFeedbackSsrc = 123;
  static constexpr uint32_t kSenderSsrc = 12345;
  SimulatedClock clock(100'000'000);
  RtcpTransceiverConfig config;
  config.clock = &clock;
  config.feedback_ssrc = kFeedbackSsrc;
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(clock.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(), clock.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(RtcpTransceiverImplTest,
     MaySendBothSenderReportAndReceiverReportInTheSamePacket) {
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&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.outgoing_transport = &transport;
  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(transport.num_packets(), 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(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;
  SimulatedClock clock(100'000'000);
  // 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();
  receiver_config.clock = &clock;
  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]);
  }

  MockTransport transport;
  EXPECT_CALL(transport, SendRtcp)
      .Times(kNumSenders)
      .WillRepeatedly([&](const uint8_t* data, size_t size) {
        rtcp_receiver.ReceivePacket(rtc::MakeArrayView(data, size),
                                    clock.CurrentTime());
        return true;
      });
  RtcpTransceiverConfig config = DefaultTestConfig();
  config.clock = &clock;
  config.outgoing_transport = &transport;
  // 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(RtcpTransceiverImplTest, SkipsSenderReportForInactiveSender) {
  static constexpr uint32_t kSenderSsrc[] = {12345, 23456};
  RtcpTransceiverConfig config = DefaultTestConfig();
  RtcpPacketParser rtcp_parser;
  RtcpParserTransport transport(&rtcp_parser);
  config.outgoing_transport = &transport;
  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(transport.num_packets(), 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(transport.num_packets(), 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(transport.num_packets(), 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(transport.num_packets(), 4);
  EXPECT_EQ(rtcp_parser.sender_report()->num_packets(), 6);
}

}  // namespace
}  // namespace webrtc
