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

#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <utility>

#include "api/array_view.h"
#include "api/call/transport.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/transport/network_types.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/video_timing.h"
#include "modules/rtp_rtcp/include/flexfec_sender.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_header_extension_size.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_history.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
#include "rtc_base/checks.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {
namespace {

using ::testing::_;
using ::testing::AllOf;
using ::testing::Eq;
using ::testing::Field;
using ::testing::InSequence;
using ::testing::NiceMock;
using ::testing::StrictMock;

constexpr Timestamp kStartTime = Timestamp::Millis(123456789);
constexpr int kDefaultPayloadType = 100;
constexpr int kFlexfectPayloadType = 110;
constexpr uint16_t kStartSequenceNumber = 33;
constexpr uint32_t kSsrc = 725242;
constexpr uint32_t kRtxSsrc = 12345;
constexpr uint32_t kFlexFecSsrc = 23456;
enum : int {
  kTransportSequenceNumberExtensionId = 1,
  kAbsoluteSendTimeExtensionId,
  kTransmissionOffsetExtensionId,
  kVideoTimingExtensionId,
};

class MockSendPacketObserver : public SendPacketObserver {
 public:
  MOCK_METHOD(void,
              OnSendPacket,
              (std::optional<uint16_t>, Timestamp, uint32_t),
              (override));
};

class MockStreamDataCountersCallback : public StreamDataCountersCallback {
 public:
  MOCK_METHOD(void,
              DataCountersUpdated,
              (const StreamDataCounters& counters, uint32_t ssrc),
              (override));
};

struct TransmittedPacket {
  TransmittedPacket(rtc::ArrayView<const uint8_t> data,
                    const PacketOptions& packet_options,
                    RtpHeaderExtensionMap* extensions)
      : packet(extensions), options(packet_options) {
    EXPECT_TRUE(packet.Parse(data));
  }
  RtpPacketReceived packet;
  PacketOptions options;
};

class TestTransport : public Transport {
 public:
  explicit TestTransport(RtpHeaderExtensionMap* extensions)
      : total_data_sent_(DataSize::Zero()), extensions_(extensions) {}
  MOCK_METHOD(void, SentRtp, (const PacketOptions& options), ());
  bool SendRtp(rtc::ArrayView<const uint8_t> packet,
               const PacketOptions& options) override {
    total_data_sent_ += DataSize::Bytes(packet.size());
    last_packet_.emplace(packet, options, extensions_);
    SentRtp(options);
    return true;
  }

  bool SendRtcp(rtc::ArrayView<const uint8_t>) override {
    RTC_CHECK_NOTREACHED();
  }

  std::optional<TransmittedPacket> last_packet() { return last_packet_; }

 private:
  DataSize total_data_sent_;
  std::optional<TransmittedPacket> last_packet_;
  RtpHeaderExtensionMap* const extensions_;
};

}  // namespace

class RtpSenderEgressTest : public ::testing::Test {
 protected:
  RtpSenderEgressTest()
      : time_controller_(kStartTime),
        env_(CreateEnvironment(time_controller_.GetClock())),
        transport_(&header_extensions_),
        packet_history_(env_,
                        RtpPacketHistory::PaddingMode::kRecentLargePacket),
        sequence_number_(kStartSequenceNumber) {}

  std::unique_ptr<RtpSenderEgress> CreateRtpSenderEgress() {
    return std::make_unique<RtpSenderEgress>(env_, DefaultConfig(),
                                             &packet_history_);
  }

  RtpRtcpInterface::Configuration DefaultConfig() {
    RtpRtcpInterface::Configuration config;
    config.audio = false;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.rtx_send_ssrc = kRtxSsrc;
    config.fec_generator = nullptr;
    config.send_packet_observer = &send_packet_observer_;
    config.rtp_stats_callback = &mock_rtp_stats_callback_;
    config.populate_network2_timestamp = false;
    return config;
  }

  std::unique_ptr<RtpPacketToSend> BuildRtpPacket(bool marker_bit,
                                                  int64_t capture_time_ms) {
    auto packet = std::make_unique<RtpPacketToSend>(&header_extensions_);
    packet->SetSsrc(kSsrc);
    packet->ReserveExtension<AbsoluteSendTime>();
    packet->ReserveExtension<TransmissionOffset>();
    packet->ReserveExtension<TransportSequenceNumber>();

    packet->SetPayloadType(kDefaultPayloadType);
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->SetMarker(marker_bit);
    packet->SetTimestamp(capture_time_ms * 90);
    packet->set_capture_time(Timestamp::Millis(capture_time_ms));
    packet->SetSequenceNumber(sequence_number_++);
    return packet;
  }

  std::unique_ptr<RtpPacketToSend> BuildRtpPacket() {
    return BuildRtpPacket(/*marker_bit=*/true, env_.clock().CurrentTime().ms());
  }

  GlobalSimulatedTimeController time_controller_;
  const Environment env_;
  NiceMock<MockStreamDataCountersCallback> mock_rtp_stats_callback_;
  NiceMock<MockSendPacketObserver> send_packet_observer_;
  RtpHeaderExtensionMap header_extensions_;
  NiceMock<TestTransport> transport_;
  RtpPacketHistory packet_history_;
  uint16_t sequence_number_;
};

TEST_F(RtpSenderEgressTest, SendsPacketsOneByOneWhenNotBatching) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  EXPECT_CALL(transport_,
              SentRtp(AllOf(Field(&PacketOptions::last_packet_in_batch, false),
                            Field(&PacketOptions::batchable, false))));
  sender->SendPacket(BuildRtpPacket(), PacedPacketInfo());
}

TEST_F(RtpSenderEgressTest, SendsPacketsOneByOneWhenBatchingWithAudio) {
  auto config = DefaultConfig();
  config.enable_send_packet_batching = true;
  config.audio = true;
  auto sender =
      std::make_unique<RtpSenderEgress>(env_, config, &packet_history_);
  EXPECT_CALL(transport_,
              SentRtp(AllOf(Field(&PacketOptions::last_packet_in_batch, false),
                            Field(&PacketOptions::batchable, false))))
      .Times(2);
  sender->SendPacket(BuildRtpPacket(), PacedPacketInfo());
  sender->SendPacket(BuildRtpPacket(), PacedPacketInfo());
}

TEST_F(RtpSenderEgressTest, CollectsPacketsWhenBatchingWithVideo) {
  auto config = DefaultConfig();
  config.enable_send_packet_batching = true;
  RtpSenderEgress sender(env_, config, &packet_history_);
  sender.SendPacket(BuildRtpPacket(), PacedPacketInfo());
  sender.SendPacket(BuildRtpPacket(), PacedPacketInfo());
  InSequence s;
  EXPECT_CALL(transport_,
              SentRtp(AllOf(Field(&PacketOptions::last_packet_in_batch, false),
                            Field(&PacketOptions::batchable, true))));
  EXPECT_CALL(transport_,
              SentRtp(AllOf(Field(&PacketOptions::last_packet_in_batch, true),
                            Field(&PacketOptions::batchable, true))));
  sender.OnBatchComplete();
}

TEST_F(RtpSenderEgressTest, PacketOptionsIsMediaSetByPacketType) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  std::unique_ptr<RtpPacketToSend> media_packet = BuildRtpPacket();
  auto sequence_number = media_packet->SequenceNumber();
  media_packet->set_packet_type(RtpPacketMediaType::kVideo);
  sender->SendPacket(std::move(media_packet), PacedPacketInfo());
  EXPECT_TRUE(transport_.last_packet()->options.is_media);

  std::unique_ptr<RtpPacketToSend> retransmission = BuildRtpPacket();
  retransmission->set_packet_type(RtpPacketMediaType::kRetransmission);
  retransmission->set_retransmitted_sequence_number(sequence_number);
  sender->SendPacket(std::move(retransmission), PacedPacketInfo());
  EXPECT_FALSE(transport_.last_packet()->options.is_media);
}

TEST_F(RtpSenderEgressTest, DoesnSetIncludedInAllocationByDefault) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  sender->SendPacket(std::move(packet), PacedPacketInfo());
  EXPECT_FALSE(transport_.last_packet()->options.included_in_feedback);
  EXPECT_FALSE(transport_.last_packet()->options.included_in_allocation);
}

TEST_F(RtpSenderEgressTest,
       SetsIncludedInFeedbackWhenTransportSequenceNumberExtensionIsRegistered) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  header_extensions_.RegisterByUri(kTransportSequenceNumberExtensionId,
                                   TransportSequenceNumber::Uri());
  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_transport_sequence_number(1);
  sender->SendPacket(std::move(packet), PacedPacketInfo());
  EXPECT_TRUE(transport_.last_packet()->options.included_in_feedback);
}

TEST_F(
    RtpSenderEgressTest,
    SetsIncludedInAllocationWhenTransportSequenceNumberExtensionIsRegistered) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  header_extensions_.RegisterByUri(kTransportSequenceNumberExtensionId,
                                   TransportSequenceNumber::Uri());
  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_transport_sequence_number(1);
  sender->SendPacket(std::move(packet), PacedPacketInfo());
  EXPECT_TRUE(transport_.last_packet()->options.included_in_allocation);
}

TEST_F(RtpSenderEgressTest,
       SetsIncludedInAllocationWhenForcedAsPartOfAllocation) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  sender->ForceIncludeSendPacketsInAllocation(true);

  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  sender->SendPacket(std::move(packet), PacedPacketInfo());
  EXPECT_FALSE(transport_.last_packet()->options.included_in_feedback);
  EXPECT_TRUE(transport_.last_packet()->options.included_in_allocation);
}

TEST_F(RtpSenderEgressTest,
       DoesntWriteTransmissionOffsetOnRtxPaddingBeforeMedia) {
  header_extensions_.RegisterByUri(kTransmissionOffsetExtensionId,
                                   TransmissionOffset::Uri());

  // Prior to sending media, timestamps are 0.
  std::unique_ptr<RtpPacketToSend> padding =
      BuildRtpPacket(/*marker_bit=*/true, /*capture_time_ms=*/0);
  padding->set_packet_type(RtpPacketMediaType::kPadding);
  padding->SetSsrc(kRtxSsrc);
  EXPECT_TRUE(padding->HasExtension<TransmissionOffset>());

  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  sender->SendPacket(std::move(padding), PacedPacketInfo());

  std::optional<int32_t> offset =
      transport_.last_packet()->packet.GetExtension<TransmissionOffset>();
  EXPECT_EQ(offset, 0);
}

TEST_F(RtpSenderEgressTest, WritesPacerExitToTimingExtension) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  header_extensions_.RegisterByUri(kVideoTimingExtensionId,
                                   VideoTimingExtension::Uri());

  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->SetExtension<VideoTimingExtension>(VideoSendTiming{});

  const int kStoredTimeInMs = 100;
  time_controller_.AdvanceTime(TimeDelta::Millis(kStoredTimeInMs));
  sender->SendPacket(std::move(packet), PacedPacketInfo());
  ASSERT_TRUE(transport_.last_packet().has_value());

  VideoSendTiming video_timing;
  EXPECT_TRUE(
      transport_.last_packet()->packet.GetExtension<VideoTimingExtension>(
          &video_timing));
  EXPECT_EQ(video_timing.pacer_exit_delta_ms, kStoredTimeInMs);
}

TEST_F(RtpSenderEgressTest, WritesNetwork2ToTimingExtension) {
  RtpRtcpInterface::Configuration rtp_config = DefaultConfig();
  rtp_config.populate_network2_timestamp = true;
  RtpSenderEgress sender(env_, rtp_config, &packet_history_);
  header_extensions_.RegisterByUri(kVideoTimingExtensionId,
                                   VideoTimingExtension::Uri());

  const uint16_t kPacerExitMs = 1234u;
  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  VideoSendTiming send_timing = {};
  send_timing.pacer_exit_delta_ms = kPacerExitMs;
  packet->SetExtension<VideoTimingExtension>(send_timing);

  const int kStoredTimeInMs = 100;
  time_controller_.AdvanceTime(TimeDelta::Millis(kStoredTimeInMs));
  sender.SendPacket(std::move(packet), PacedPacketInfo());
  ASSERT_TRUE(transport_.last_packet().has_value());

  VideoSendTiming video_timing;
  EXPECT_TRUE(
      transport_.last_packet()->packet.GetExtension<VideoTimingExtension>(
          &video_timing));
  EXPECT_EQ(video_timing.network2_timestamp_delta_ms, kStoredTimeInMs);
  EXPECT_EQ(video_timing.pacer_exit_delta_ms, kPacerExitMs);
}

TEST_F(RtpSenderEgressTest, WritesTransportSequenceNumberExtensionIfAllocated) {
  RtpSenderEgress sender(env_, DefaultConfig(), &packet_history_);
  header_extensions_.RegisterByUri(kTransportSequenceNumberExtensionId,
                                   TransportSequenceNumber::Uri());
  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  ASSERT_TRUE(packet->HasExtension<TransportSequenceNumber>());
  const int64_t kTransportSequenceNumber = 0xFFFF000F;
  packet->set_transport_sequence_number(kTransportSequenceNumber);

  sender.SendPacket(std::move(packet), PacedPacketInfo());

  ASSERT_TRUE(transport_.last_packet().has_value());
  EXPECT_EQ(
      transport_.last_packet()->packet.GetExtension<TransportSequenceNumber>(),
      kTransportSequenceNumber & 0xFFFF);
}

TEST_F(RtpSenderEgressTest, OnSendPacketUpdated) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  header_extensions_.RegisterByUri(kTransportSequenceNumberExtensionId,
                                   TransportSequenceNumber::Uri());

  const uint16_t kTransportSequenceNumber = 1;
  EXPECT_CALL(send_packet_observer_,
              OnSendPacket(Eq(kTransportSequenceNumber),
                           env_.clock().CurrentTime(), kSsrc));
  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_transport_sequence_number(kTransportSequenceNumber);
  sender->SendPacket(std::move(packet), PacedPacketInfo());
}

TEST_F(RtpSenderEgressTest, OnSendPacketUpdatedWithoutTransportSequenceNumber) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  EXPECT_CALL(
      send_packet_observer_,
      OnSendPacket(Eq(std::nullopt), env_.clock().CurrentTime(), kSsrc));
  sender->SendPacket(BuildRtpPacket(), PacedPacketInfo());
}

TEST_F(RtpSenderEgressTest, OnSendPacketNotUpdatedForRetransmits) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  header_extensions_.RegisterByUri(kTransportSequenceNumberExtensionId,
                                   TransportSequenceNumber::Uri());

  const uint16_t kTransportSequenceNumber = 1;
  EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(0);
  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_transport_sequence_number(kTransportSequenceNumber);
  packet->set_packet_type(RtpPacketMediaType::kRetransmission);
  packet->set_retransmitted_sequence_number(packet->SequenceNumber());
  packet->set_original_ssrc(packet->Ssrc());
  sender->SendPacket(std::move(packet), PacedPacketInfo());
}

TEST_F(RtpSenderEgressTest, ReportsFecRate) {
  constexpr int kNumPackets = 10;
  constexpr TimeDelta kTimeBetweenPackets = TimeDelta::Millis(33);

  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  DataSize total_fec_data_sent = DataSize::Zero();
  // Send some packets, alternating between media and FEC.
  for (size_t i = 0; i < kNumPackets; ++i) {
    std::unique_ptr<RtpPacketToSend> media_packet = BuildRtpPacket();
    media_packet->set_packet_type(RtpPacketMediaType::kVideo);
    media_packet->SetPayloadSize(500);
    sender->SendPacket(std::move(media_packet), PacedPacketInfo());

    std::unique_ptr<RtpPacketToSend> fec_packet = BuildRtpPacket();
    fec_packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
    fec_packet->SetPayloadSize(123);
    auto fec_packet_size = fec_packet->size();
    sender->SendPacket(std::move(fec_packet), PacedPacketInfo());
    total_fec_data_sent += DataSize::Bytes(fec_packet_size);

    time_controller_.AdvanceTime(kTimeBetweenPackets);
  }

  EXPECT_NEAR(
      (sender->GetSendRates(
           time_controller_.GetClock()
               ->CurrentTime())[RtpPacketMediaType::kForwardErrorCorrection])
          .bps(),
      (total_fec_data_sent / (kTimeBetweenPackets * kNumPackets)).bps(), 500);
}

TEST_F(RtpSenderEgressTest, BitrateCallbacks) {
  class MockBitrateStaticsObserver : public BitrateStatisticsObserver {
   public:
    MOCK_METHOD(void, Notify, (uint32_t, uint32_t, uint32_t), (override));
  } observer;

  RtpRtcpInterface::Configuration config = DefaultConfig();
  config.send_bitrate_observer = &observer;
  RtpSenderEgress sender(env_, config, &packet_history_);

  // Simulate kNumPackets sent with kPacketInterval intervals, with the
  // number of packets selected so that we fill (but don't overflow) the one
  // second averaging window.
  const TimeDelta kWindowSize = TimeDelta::Seconds(1);
  const TimeDelta kPacketInterval = TimeDelta::Millis(20);
  const int kNumPackets = (kWindowSize - kPacketInterval) / kPacketInterval;

  DataSize total_data_sent = DataSize::Zero();

  // Send all but on of the packets, expect a call for each packet but don't
  // verify bitrate yet (noisy measurements in the beginning).
  for (int i = 0; i < kNumPackets; ++i) {
    std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
    packet->SetPayloadSize(500);
    // Mark all packets as retransmissions - will cause total and retransmission
    // rates to be equal.
    packet->set_packet_type(RtpPacketMediaType::kRetransmission);
    packet->set_retransmitted_sequence_number(packet->SequenceNumber());
    total_data_sent += DataSize::Bytes(packet->size());

    EXPECT_CALL(observer, Notify(_, _, kSsrc))
        .WillOnce([&](uint32_t total_bitrate_bps,
                      uint32_t retransmission_bitrate_bps, uint32_t /*ssrc*/) {
          TimeDelta window_size = i * kPacketInterval + TimeDelta::Millis(1);
          // If there is just a single data point, there is no well defined
          // averaging window so a bitrate of zero will be reported.
          const double expected_bitrate_bps =
              i == 0 ? 0.0 : (total_data_sent / window_size).bps();
          EXPECT_NEAR(total_bitrate_bps, expected_bitrate_bps, 500);
          EXPECT_NEAR(retransmission_bitrate_bps, expected_bitrate_bps, 500);
        });

    sender.SendPacket(std::move(packet), PacedPacketInfo());
    time_controller_.AdvanceTime(kPacketInterval);
  }
}

TEST_F(RtpSenderEgressTest, DoesNotPutNotRetransmittablePacketsInHistory) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  packet_history_.SetStorePacketsStatus(
      RtpPacketHistory::StorageMode::kStoreAndCull, 10);

  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_allow_retransmission(false);
  auto packet_sequence_number = packet->SequenceNumber();
  sender->SendPacket(std::move(packet), PacedPacketInfo());
  EXPECT_FALSE(packet_history_.GetPacketState(packet_sequence_number));
}

TEST_F(RtpSenderEgressTest, PutsRetransmittablePacketsInHistory) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  packet_history_.SetStorePacketsStatus(
      RtpPacketHistory::StorageMode::kStoreAndCull, 10);

  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_allow_retransmission(true);
  auto packet_sequence_number = packet->SequenceNumber();
  sender->SendPacket(std::move(packet), PacedPacketInfo());
  EXPECT_TRUE(packet_history_.GetPacketState(packet_sequence_number));
}

TEST_F(RtpSenderEgressTest, DoesNotPutNonMediaInHistory) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  packet_history_.SetStorePacketsStatus(
      RtpPacketHistory::StorageMode::kStoreAndCull, 10);

  // Non-media packets, even when marked as retransmittable, are not put into
  // the packet history.
  std::unique_ptr<RtpPacketToSend> retransmission = BuildRtpPacket();
  retransmission->set_allow_retransmission(true);
  retransmission->set_packet_type(RtpPacketMediaType::kRetransmission);
  retransmission->set_retransmitted_sequence_number(
      retransmission->SequenceNumber());
  auto retransmission_sequence_number = retransmission->SequenceNumber();
  sender->SendPacket(std::move(retransmission), PacedPacketInfo());
  EXPECT_FALSE(packet_history_.GetPacketState(retransmission_sequence_number));

  std::unique_ptr<RtpPacketToSend> fec = BuildRtpPacket();
  fec->set_allow_retransmission(true);
  fec->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
  auto fec_sequence_number = fec->SequenceNumber();
  sender->SendPacket(std::move(fec), PacedPacketInfo());
  EXPECT_FALSE(packet_history_.GetPacketState(fec_sequence_number));

  std::unique_ptr<RtpPacketToSend> padding = BuildRtpPacket();
  padding->set_allow_retransmission(true);
  padding->set_packet_type(RtpPacketMediaType::kPadding);
  auto padding_sequence_number = padding->SequenceNumber();
  sender->SendPacket(std::move(padding), PacedPacketInfo());
  EXPECT_FALSE(packet_history_.GetPacketState(padding_sequence_number));
}

TEST_F(RtpSenderEgressTest, UpdatesSendStatusOfRetransmittedPackets) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  packet_history_.SetStorePacketsStatus(
      RtpPacketHistory::StorageMode::kStoreAndCull, 10);

  // Send a packet, putting it in the history.
  std::unique_ptr<RtpPacketToSend> media_packet = BuildRtpPacket();
  media_packet->set_allow_retransmission(true);
  auto media_packet_sequence_number = media_packet->SequenceNumber();
  sender->SendPacket(std::move(media_packet), PacedPacketInfo());
  EXPECT_TRUE(packet_history_.GetPacketState(media_packet_sequence_number));

  // Simulate a retransmission, marking the packet as pending.
  std::unique_ptr<RtpPacketToSend> retransmission =
      packet_history_.GetPacketAndMarkAsPending(media_packet_sequence_number);
  retransmission->set_retransmitted_sequence_number(
      media_packet_sequence_number);
  retransmission->set_packet_type(RtpPacketMediaType::kRetransmission);
  EXPECT_TRUE(packet_history_.GetPacketState(media_packet_sequence_number));

  // Simulate packet leaving pacer, the packet should be marked as non-pending.
  sender->SendPacket(std::move(retransmission), PacedPacketInfo());
  EXPECT_TRUE(packet_history_.GetPacketState(media_packet_sequence_number));
}

TEST_F(RtpSenderEgressTest, StreamDataCountersCallbacks) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  const RtpPacketCounter kEmptyCounter;
  RtpPacketCounter expected_transmitted_counter;
  RtpPacketCounter expected_retransmission_counter;

  // Send a media packet.
  std::unique_ptr<RtpPacketToSend> media_packet = BuildRtpPacket();
  media_packet->SetPayloadSize(6);
  media_packet->SetSequenceNumber(kStartSequenceNumber);
  media_packet->set_time_in_send_queue(TimeDelta::Millis(10));
  expected_transmitted_counter.packets += 1;
  expected_transmitted_counter.payload_bytes += media_packet->payload_size();
  expected_transmitted_counter.header_bytes += media_packet->headers_size();
  expected_transmitted_counter.total_packet_delay += TimeDelta::Millis(10);

  EXPECT_CALL(
      mock_rtp_stats_callback_,
      DataCountersUpdated(AllOf(Field(&StreamDataCounters::transmitted,
                                      expected_transmitted_counter),
                                Field(&StreamDataCounters::retransmitted,
                                      expected_retransmission_counter),
                                Field(&StreamDataCounters::fec, kEmptyCounter)),
                          kSsrc));
  sender->SendPacket(std::move(media_packet), PacedPacketInfo());
  time_controller_.AdvanceTime(TimeDelta::Zero());

  // Send a retransmission. Retransmissions are counted into both transmitted
  // and retransmitted packet statistics.
  std::unique_ptr<RtpPacketToSend> retransmission_packet = BuildRtpPacket();
  retransmission_packet->set_packet_type(RtpPacketMediaType::kRetransmission);
  retransmission_packet->SetSequenceNumber(kStartSequenceNumber);
  retransmission_packet->set_retransmitted_sequence_number(
      kStartSequenceNumber);
  retransmission_packet->set_time_in_send_queue(TimeDelta::Millis(20));
  expected_transmitted_counter.packets += 1;
  expected_transmitted_counter.payload_bytes +=
      retransmission_packet->payload_size();
  expected_transmitted_counter.header_bytes +=
      retransmission_packet->headers_size();
  expected_transmitted_counter.total_packet_delay += TimeDelta::Millis(20);

  expected_retransmission_counter.packets += 1;
  expected_retransmission_counter.payload_bytes +=
      retransmission_packet->payload_size();
  expected_retransmission_counter.header_bytes +=
      retransmission_packet->headers_size();
  expected_retransmission_counter.total_packet_delay += TimeDelta::Millis(20);

  EXPECT_CALL(
      mock_rtp_stats_callback_,
      DataCountersUpdated(AllOf(Field(&StreamDataCounters::transmitted,
                                      expected_transmitted_counter),
                                Field(&StreamDataCounters::retransmitted,
                                      expected_retransmission_counter),
                                Field(&StreamDataCounters::fec, kEmptyCounter)),
                          kSsrc));
  sender->SendPacket(std::move(retransmission_packet), PacedPacketInfo());
  time_controller_.AdvanceTime(TimeDelta::Zero());

  // Send a padding packet.
  std::unique_ptr<RtpPacketToSend> padding_packet = BuildRtpPacket();
  padding_packet->set_packet_type(RtpPacketMediaType::kPadding);
  padding_packet->SetPadding(224);
  padding_packet->SetSequenceNumber(kStartSequenceNumber + 1);
  padding_packet->set_time_in_send_queue(TimeDelta::Millis(30));
  expected_transmitted_counter.packets += 1;
  expected_transmitted_counter.padding_bytes += padding_packet->padding_size();
  expected_transmitted_counter.header_bytes += padding_packet->headers_size();
  expected_transmitted_counter.total_packet_delay += TimeDelta::Millis(30);

  EXPECT_CALL(
      mock_rtp_stats_callback_,
      DataCountersUpdated(AllOf(Field(&StreamDataCounters::transmitted,
                                      expected_transmitted_counter),
                                Field(&StreamDataCounters::retransmitted,
                                      expected_retransmission_counter),
                                Field(&StreamDataCounters::fec, kEmptyCounter)),
                          kSsrc));
  sender->SendPacket(std::move(padding_packet), PacedPacketInfo());
  time_controller_.AdvanceTime(TimeDelta::Zero());
}

TEST_F(RtpSenderEgressTest, StreamDataCountersCallbacksFec) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  const RtpPacketCounter kEmptyCounter;
  RtpPacketCounter expected_transmitted_counter;
  RtpPacketCounter expected_fec_counter;

  // Send a media packet.
  std::unique_ptr<RtpPacketToSend> media_packet = BuildRtpPacket();
  media_packet->SetPayloadSize(6);
  expected_transmitted_counter.packets += 1;
  expected_transmitted_counter.payload_bytes += media_packet->payload_size();
  expected_transmitted_counter.header_bytes += media_packet->headers_size();

  EXPECT_CALL(
      mock_rtp_stats_callback_,
      DataCountersUpdated(
          AllOf(Field(&StreamDataCounters::transmitted,
                      expected_transmitted_counter),
                Field(&StreamDataCounters::retransmitted, kEmptyCounter),
                Field(&StreamDataCounters::fec, expected_fec_counter)),
          kSsrc));
  sender->SendPacket(std::move(media_packet), PacedPacketInfo());
  time_controller_.AdvanceTime(TimeDelta::Zero());

  // Send and FEC packet. FEC is counted into both transmitted and FEC packet
  // statistics.
  std::unique_ptr<RtpPacketToSend> fec_packet = BuildRtpPacket();
  fec_packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
  fec_packet->SetPayloadSize(6);
  expected_transmitted_counter.packets += 1;
  expected_transmitted_counter.payload_bytes += fec_packet->payload_size();
  expected_transmitted_counter.header_bytes += fec_packet->headers_size();

  expected_fec_counter.packets += 1;
  expected_fec_counter.payload_bytes += fec_packet->payload_size();
  expected_fec_counter.header_bytes += fec_packet->headers_size();

  EXPECT_CALL(
      mock_rtp_stats_callback_,
      DataCountersUpdated(
          AllOf(Field(&StreamDataCounters::transmitted,
                      expected_transmitted_counter),
                Field(&StreamDataCounters::retransmitted, kEmptyCounter),
                Field(&StreamDataCounters::fec, expected_fec_counter)),
          kSsrc));
  sender->SendPacket(std::move(fec_packet), PacedPacketInfo());
  time_controller_.AdvanceTime(TimeDelta::Zero());
}

TEST_F(RtpSenderEgressTest, UpdatesDataCounters) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  const RtpPacketCounter kEmptyCounter;

  // Send a media packet.
  std::unique_ptr<RtpPacketToSend> media_packet = BuildRtpPacket();
  media_packet->SetPayloadSize(6);
  auto media_packet_sequence_number = media_packet->SequenceNumber();
  auto media_packet_payload_size = media_packet->payload_size();
  auto media_packet_padding_size = media_packet->padding_size();
  auto media_packet_headers_size = media_packet->headers_size();
  sender->SendPacket(std::move(media_packet), PacedPacketInfo());
  time_controller_.AdvanceTime(TimeDelta::Zero());

  // Send an RTX retransmission packet.
  std::unique_ptr<RtpPacketToSend> rtx_packet = BuildRtpPacket();
  rtx_packet->set_packet_type(RtpPacketMediaType::kRetransmission);
  rtx_packet->SetSsrc(kRtxSsrc);
  rtx_packet->SetPayloadSize(7);
  rtx_packet->set_retransmitted_sequence_number(media_packet_sequence_number);
  auto rtx_packet_payload_size = rtx_packet->payload_size();
  auto rtx_packet_padding_size = rtx_packet->padding_size();
  auto rtx_packet_headers_size = rtx_packet->headers_size();
  sender->SendPacket(std::move(rtx_packet), PacedPacketInfo());
  time_controller_.AdvanceTime(TimeDelta::Zero());

  StreamDataCounters rtp_stats;
  StreamDataCounters rtx_stats;
  sender->GetDataCounters(&rtp_stats, &rtx_stats);

  EXPECT_EQ(rtp_stats.transmitted.packets, 1u);
  EXPECT_EQ(rtp_stats.transmitted.payload_bytes, media_packet_payload_size);
  EXPECT_EQ(rtp_stats.transmitted.padding_bytes, media_packet_padding_size);
  EXPECT_EQ(rtp_stats.transmitted.header_bytes, media_packet_headers_size);
  EXPECT_EQ(rtp_stats.retransmitted, kEmptyCounter);
  EXPECT_EQ(rtp_stats.fec, kEmptyCounter);

  // Retransmissions are counted both into transmitted and retransmitted
  // packet counts.
  EXPECT_EQ(rtx_stats.transmitted.packets, 1u);
  EXPECT_EQ(rtx_stats.transmitted.payload_bytes, rtx_packet_payload_size);
  EXPECT_EQ(rtx_stats.transmitted.padding_bytes, rtx_packet_padding_size);
  EXPECT_EQ(rtx_stats.transmitted.header_bytes, rtx_packet_headers_size);
  EXPECT_EQ(rtx_stats.retransmitted, rtx_stats.transmitted);
  EXPECT_EQ(rtx_stats.fec, kEmptyCounter);
}

TEST_F(RtpSenderEgressTest, SendPacketUpdatesExtensions) {
  header_extensions_.RegisterByUri(kVideoTimingExtensionId,
                                   VideoTimingExtension::Uri());
  header_extensions_.RegisterByUri(kAbsoluteSendTimeExtensionId,
                                   AbsoluteSendTime::Uri());
  header_extensions_.RegisterByUri(kTransmissionOffsetExtensionId,
                                   TransmissionOffset::Uri());
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();

  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_packetization_finish_time(env_.clock().CurrentTime());

  const int32_t kDiffMs = 10;
  time_controller_.AdvanceTime(TimeDelta::Millis(kDiffMs));

  sender->SendPacket(std::move(packet), PacedPacketInfo());

  RtpPacketReceived received_packet = transport_.last_packet()->packet;

  EXPECT_EQ(received_packet.GetExtension<TransmissionOffset>(), kDiffMs * 90);

  EXPECT_EQ(received_packet.GetExtension<AbsoluteSendTime>(),
            AbsoluteSendTime::To24Bits(env_.clock().CurrentTime()));

  VideoSendTiming timing;
  EXPECT_TRUE(received_packet.GetExtension<VideoTimingExtension>(&timing));
  EXPECT_EQ(timing.pacer_exit_delta_ms, kDiffMs);
}

TEST_F(RtpSenderEgressTest, SendPacketSetsPacketOptions) {
  const uint16_t kPacketId = 42;
  const uint16_t kSequenceNumber = 456;
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  header_extensions_.RegisterByUri(kTransportSequenceNumberExtensionId,
                                   TransportSequenceNumber::Uri());

  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  uint32_t ssrc = packet->Ssrc();
  packet->SetSequenceNumber(kSequenceNumber);
  packet->set_transport_sequence_number(kPacketId);
  EXPECT_CALL(send_packet_observer_, OnSendPacket);
  sender->SendPacket(std::move(packet), PacedPacketInfo());

  PacketOptions packet_options = transport_.last_packet()->options;

  EXPECT_EQ(packet_options.packet_id, kPacketId);
  EXPECT_TRUE(packet_options.included_in_allocation);
  EXPECT_TRUE(packet_options.included_in_feedback);
  EXPECT_TRUE(packet_options.is_media);

  // Send another packet as retransmission, verify options are populated.
  std::unique_ptr<RtpPacketToSend> retransmission = BuildRtpPacket();
  retransmission->set_transport_sequence_number(kPacketId + 1);
  retransmission->set_packet_type(RtpPacketMediaType::kRetransmission);
  retransmission->set_retransmitted_sequence_number(kSequenceNumber);
  retransmission->set_original_ssrc(ssrc);
  sender->SendPacket(std::move(retransmission), PacedPacketInfo());
  EXPECT_FALSE(transport_.last_packet()->options.is_media);
}

TEST_F(RtpSenderEgressTest, SendPacketSetsPacketOptionsIdFromExtension) {
  header_extensions_.RegisterByUri(kTransportSequenceNumberExtensionId,
                                   TransportSequenceNumber::Uri());
  RtpSenderEgress sender(env_, DefaultConfig(), &packet_history_);

  // 64-bit transport sequence number.
  const int64_t kTransportSequenceNumber = 0xFFFF000F;
  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_transport_sequence_number(kTransportSequenceNumber);

  EXPECT_CALL(send_packet_observer_, OnSendPacket);
  sender.SendPacket(std::move(packet), PacedPacketInfo());

  ASSERT_TRUE(transport_.last_packet().has_value());
  EXPECT_EQ(
      transport_.last_packet()->packet.GetExtension<TransportSequenceNumber>(),
      kTransportSequenceNumber & 0xFFFF);
  PacketOptions packet_options = transport_.last_packet()->options;
  // 16 bit packet id.
  EXPECT_EQ(packet_options.packet_id, kTransportSequenceNumber & 0xFFFF);
}

TEST_F(RtpSenderEgressTest,
       SendPacketSetsPacketOptionsIdFromRtpSendPacketIfNotUsingExtension) {
  RtpSenderEgress sender(env_, DefaultConfig(), &packet_history_);
  // 64-bit transport sequence number.
  const int64_t kTransportSequenceNumber = 0xFFFF000F;
  std::unique_ptr<RtpPacketToSend> packet = BuildRtpPacket();
  packet->set_transport_sequence_number(kTransportSequenceNumber);

  EXPECT_CALL(send_packet_observer_, OnSendPacket);
  sender.SendPacket(std::move(packet), PacedPacketInfo());

  ASSERT_TRUE(transport_.last_packet().has_value());
  ASSERT_FALSE(
      transport_.last_packet()->packet.HasExtension<TransportSequenceNumber>());
  PacketOptions packet_options = transport_.last_packet()->options;
  EXPECT_EQ(packet_options.packet_id, kTransportSequenceNumber);
}

TEST_F(RtpSenderEgressTest, SendPacketUpdatesStats) {
  const size_t kPayloadSize = 1000;

  const rtc::ArrayView<const RtpExtensionSize> kNoRtpHeaderExtensionSizes;
  FlexfecSender flexfec(env_, kFlexfectPayloadType, kFlexFecSsrc, kSsrc,
                        /*mid=*/"",
                        /*header_extensions=*/{}, kNoRtpHeaderExtensionSizes,
                        /*rtp_state=*/nullptr);
  RtpRtcpInterface::Configuration config = DefaultConfig();
  config.fec_generator = &flexfec;
  RtpSenderEgress sender(env_, config, &packet_history_);

  header_extensions_.RegisterByUri(kTransportSequenceNumberExtensionId,
                                   TransportSequenceNumber::Uri());

  const Timestamp capture_time = env_.clock().CurrentTime();

  std::unique_ptr<RtpPacketToSend> video_packet = BuildRtpPacket();
  video_packet->set_packet_type(RtpPacketMediaType::kVideo);
  video_packet->SetPayloadSize(kPayloadSize);
  video_packet->set_transport_sequence_number(1);

  std::unique_ptr<RtpPacketToSend> rtx_packet = BuildRtpPacket();
  rtx_packet->SetSsrc(kRtxSsrc);
  rtx_packet->set_packet_type(RtpPacketMediaType::kRetransmission);
  rtx_packet->set_original_ssrc(video_packet->Ssrc());
  rtx_packet->set_retransmitted_sequence_number(video_packet->SequenceNumber());
  rtx_packet->SetPayloadSize(kPayloadSize);
  rtx_packet->set_transport_sequence_number(2);

  std::unique_ptr<RtpPacketToSend> fec_packet = BuildRtpPacket();
  fec_packet->SetSsrc(kFlexFecSsrc);
  fec_packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
  fec_packet->SetPayloadSize(kPayloadSize);
  fec_packet->set_transport_sequence_number(3);

  const int64_t kDiffMs = 25;
  time_controller_.AdvanceTime(TimeDelta::Millis(kDiffMs));

  EXPECT_CALL(send_packet_observer_, OnSendPacket(Eq(1), capture_time, kSsrc));

  sender.SendPacket(std::move(video_packet), PacedPacketInfo());

  // Send packet observer not called for padding/retransmissions.
  EXPECT_CALL(send_packet_observer_, OnSendPacket(Eq(2), _, _)).Times(0);
  sender.SendPacket(std::move(rtx_packet), PacedPacketInfo());

  EXPECT_CALL(send_packet_observer_,
              OnSendPacket(Eq(3), capture_time, kFlexFecSsrc));
  sender.SendPacket(std::move(fec_packet), PacedPacketInfo());

  time_controller_.AdvanceTime(TimeDelta::Zero());
  StreamDataCounters rtp_stats;
  StreamDataCounters rtx_stats;
  sender.GetDataCounters(&rtp_stats, &rtx_stats);
  EXPECT_EQ(rtp_stats.transmitted.packets, 2u);
  EXPECT_EQ(rtp_stats.fec.packets, 1u);
  EXPECT_EQ(rtx_stats.retransmitted.packets, 1u);
}

TEST_F(RtpSenderEgressTest, SupportsAbortingRetransmissions) {
  std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
  packet_history_.SetStorePacketsStatus(
      RtpPacketHistory::StorageMode::kStoreAndCull, 10);

  // Create a packet and send it so it is put in the history.
  std::unique_ptr<RtpPacketToSend> media_packet = BuildRtpPacket();
  media_packet->set_packet_type(RtpPacketMediaType::kVideo);
  media_packet->set_allow_retransmission(true);
  const uint16_t media_sequence_number = media_packet->SequenceNumber();
  sender->SendPacket(std::move(media_packet), PacedPacketInfo());

  // Fetch a retranmission packet from the history, this should mark the
  // media packets as pending so it is not available to grab again.
  std::unique_ptr<RtpPacketToSend> retransmission_packet =
      packet_history_.GetPacketAndMarkAsPending(media_sequence_number);
  ASSERT_TRUE(retransmission_packet);
  EXPECT_FALSE(
      packet_history_.GetPacketAndMarkAsPending(media_sequence_number));

  // Mark retransmission as aborted, fetching packet is possible again.
  retransmission_packet.reset();
  uint16_t kAbortedSequenceNumbers[] = {media_sequence_number};
  sender->OnAbortedRetransmissions(kAbortedSequenceNumbers);
  EXPECT_TRUE(packet_history_.GetPacketAndMarkAsPending(media_sequence_number));
}

}  // namespace webrtc
