// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cast/streaming/sender.h"

#include <stdint.h>

#include <algorithm>
#include <array>
#include <chrono>
#include <limits>
#include <map>
#include <set>
#include <utility>
#include <vector>

#include "absl/types/optional.h"
#include "absl/types/span.h"
#include "cast/streaming/compound_rtcp_builder.h"
#include "cast/streaming/constants.h"
#include "cast/streaming/encoded_frame.h"
#include "cast/streaming/frame_collector.h"
#include "cast/streaming/frame_crypto.h"
#include "cast/streaming/frame_id.h"
#include "cast/streaming/mock_environment.h"
#include "cast/streaming/packet_util.h"
#include "cast/streaming/rtcp_session.h"
#include "cast/streaming/rtp_defines.h"
#include "cast/streaming/rtp_packet_parser.h"
#include "cast/streaming/sender_packet_router.h"
#include "cast/streaming/sender_report_parser.h"
#include "cast/streaming/session_config.h"
#include "cast/streaming/ssrc.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "platform/test/fake_clock.h"
#include "platform/test/fake_task_runner.h"
#include "util/alarm.h"
#include "util/chrono_helpers.h"
#include "util/yet_another_bit_vector.h"

using testing::_;
using testing::AtLeast;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::Sequence;

namespace openscreen {
namespace cast {
namespace {

// Sender configuration.
constexpr Ssrc kSenderSsrc = 1;
constexpr Ssrc kReceiverSsrc = 2;
constexpr int kRtpTimebase = 48000;
constexpr milliseconds kTargetPlayoutDelay{400};
constexpr auto kAesKey =
    std::array<uint8_t, 16>{{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}};
constexpr auto kCastIvMask =
    std::array<uint8_t, 16>{{0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
                             0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00}};
constexpr RtpPayloadType kRtpPayloadType = RtpPayloadType::kVideoVp8;

// The number of RTP ticks advanced per frame, for 100 FPS media.
constexpr int kRtpTicksPerFrame = kRtpTimebase / 100;

// The number of milliseconds advanced per frame, for 100 FPS media.
constexpr milliseconds kFrameDuration{1000 / 100};
static_assert(kFrameDuration < (kTargetPlayoutDelay / 10),
              "Kickstart test assumes frame duration is far less than the "
              "playout delay.");

// An Encoded frame that also holds onto its own copy of data.
struct EncodedFrameWithBuffer : public EncodedFrame {
  // |EncodedFrame::data| always points inside buffer.begin()...buffer.end().
  std::vector<uint8_t> buffer;
};

// SenderPacketRouter configuration for these tests.
constexpr int kNumPacketsPerBurst = 20;
constexpr milliseconds kBurstInterval{10};

// An arbitrary value, subtracted from "now," to specify the reference_time on
// frames that are about to be enqueued. This simulates that capture+encode
// happened in the past, before Sender::EnqueueFrame() is called.
constexpr milliseconds kCaptureDelay{11};

// In some tests, the computed time values could be off a little bit due to
// imprecision in certain wire-format timestamp types. The following macro
// behaves just like Gtest's EXPECT_NEAR(), but works with all the time types
// too.
#define EXPECT_NEARLY_EQUAL(duration_a, duration_b, epsilon) \
  if ((duration_a) >= (duration_b)) {                        \
    EXPECT_LE((duration_a), (duration_b) + (epsilon));       \
  } else {                                                   \
    EXPECT_GE((duration_a), (duration_b) - (epsilon));       \
  }

// Simulates UDP/IPv6 traffic in one direction (from Sender→Receiver, or
// Receiver→Sender), with a settable amount of delay.
class SimulatedNetworkPipe {
 public:
  SimulatedNetworkPipe(TaskRunner* task_runner,
                       Environment::PacketConsumer* remote)
      : task_runner_(task_runner), remote_(remote) {
    // Create a fake IPv6 address using the "documentative purposes" prefix
    // concatenated with the |this| pointer.
    std::array<uint16_t, 8> hextets{};
    hextets[0] = 0x2001;
    hextets[1] = 0x0db8;
    auto* const this_pointer = this;
    static_assert(sizeof(this_pointer) <= (6 * sizeof(uint16_t)), "");
    memcpy(&hextets[2], &this_pointer, sizeof(this_pointer));
    local_endpoint_ = IPEndpoint{IPAddress(hextets), 2344};
  }

  const IPEndpoint& local_endpoint() const { return local_endpoint_; }

  Clock::duration network_delay() const { return network_delay_; }
  void set_network_delay(Clock::duration delay) { network_delay_ = delay; }

  // The caller needs to spin the task runner before |packet| will reach the
  // other side.
  void StartPacketTransmission(std::vector<uint8_t> packet) {
    task_runner_->PostTaskWithDelay(
        [this, packet = std::move(packet)]() mutable {
          remote_->OnReceivedPacket(local_endpoint_, FakeClock::now(),
                                    std::move(packet));
        },
        network_delay_);
  }

 private:
  TaskRunner* const task_runner_;
  Environment::PacketConsumer* const remote_;

  IPEndpoint local_endpoint_;

  // The amount of time for the packet to transmit over this simulated network
  // pipe. Defaults to zero to simplify the tests that don't care about delays.
  Clock::duration network_delay_{};
};

// Processes packets from the Sender under test, allowing unit tests to set
// expectations for parsed RTP or RTCP packets, to confirm proper behavior of
// the Sender.
class MockReceiver : public Environment::PacketConsumer {
 public:
  explicit MockReceiver(SimulatedNetworkPipe* pipe_to_sender)
      : pipe_to_sender_(pipe_to_sender),
        rtcp_session_(kSenderSsrc, kReceiverSsrc, FakeClock::now()),
        sender_report_parser_(&rtcp_session_),
        rtcp_builder_(&rtcp_session_),
        rtp_parser_(kSenderSsrc),
        crypto_(kAesKey, kCastIvMask) {
    rtcp_builder_.SetPlayoutDelay(kTargetPlayoutDelay);
  }

  ~MockReceiver() override = default;

  // Simulate the Receiver ACK'ing all frames up to and including the
  // |new_checkpoint|.
  void SetCheckpointFrame(FrameId new_checkpoint) {
    OSP_CHECK_GE(new_checkpoint, rtcp_builder_.checkpoint_frame());
    rtcp_builder_.SetCheckpointFrame(new_checkpoint);
  }

  // Automatically advances the checkpoint based on what is found in
  // |complete_frames_|, returning true if the checkpoint moved forward.
  bool AutoAdvanceCheckpoint() {
    const FrameId old_checkpoint = rtcp_builder_.checkpoint_frame();
    FrameId new_checkpoint = old_checkpoint;
    for (auto it = complete_frames_.upper_bound(old_checkpoint);
         it != complete_frames_.end(); ++it) {
      if (it->first != new_checkpoint + 1) {
        break;
      }
      ++new_checkpoint;
    }
    if (new_checkpoint > old_checkpoint) {
      rtcp_builder_.SetCheckpointFrame(new_checkpoint);
      return true;
    }
    return false;
  }

  void SetPictureLossIndicator(bool picture_is_lost) {
    rtcp_builder_.SetPictureLossIndicator(picture_is_lost);
  }

  void SetReceiverReport(StatusReportId reply_for,
                         RtcpReportBlock::Delay processing_delay) {
    RtcpReportBlock receiver_report;
    receiver_report.ssrc = kSenderSsrc;
    receiver_report.last_status_report_id = reply_for;
    receiver_report.delay_since_last_report = processing_delay;
    rtcp_builder_.IncludeReceiverReportInNextPacket(receiver_report);
  }

  void SetNacksAndAcks(std::vector<PacketNack> packet_nacks,
                       std::vector<FrameId> frame_acks) {
    rtcp_builder_.IncludeFeedbackInNextPacket(std::move(packet_nacks),
                                              std::move(frame_acks));
  }

  // Builds and sends a RTCP packet containing one or more of: checkpoint, PLI,
  // Receiver Report, NACKs, ACKs.
  void TransmitRtcpFeedbackPacket() {
    uint8_t buffer[kMaxRtpPacketSizeForIpv6UdpOnEthernet];
    const absl::Span<uint8_t> packet =
        rtcp_builder_.BuildPacket(FakeClock::now(), buffer);
    pipe_to_sender_->StartPacketTransmission(
        std::vector<uint8_t>(packet.begin(), packet.end()));
  }

  // Used by tests to simulate the Receiver not seeing specific packets come in
  // from the network (e.g., because the network dropped the packets).
  void SetIgnoreList(std::vector<PacketNack> ignore_list) {
    ignore_list_ = ignore_list;
  }

  // Environment::PacketConsumer implementation.
  //
  // Called to process a packet from the Sender, simulating basic RTP frame
  // collection and Sender Report parsing/handling.
  void OnReceivedPacket(const IPEndpoint& source,
                        Clock::time_point arrival_time,
                        std::vector<uint8_t> packet) override {
    const auto type_and_ssrc = InspectPacketForRouting(packet);
    EXPECT_NE(ApparentPacketType::UNKNOWN, type_and_ssrc.first);
    EXPECT_EQ(kSenderSsrc, type_and_ssrc.second);
    if (type_and_ssrc.first == ApparentPacketType::RTP) {
      const absl::optional<RtpPacketParser::ParseResult> part_of_frame =
          rtp_parser_.Parse(packet);
      ASSERT_TRUE(part_of_frame);

      // Return early if simulating packet drops over the network.
      if (std::find_if(ignore_list_.begin(), ignore_list_.end(),
                       [&](const PacketNack& baddie) {
                         return (
                             baddie.frame_id == part_of_frame->frame_id &&
                             (baddie.packet_id == kAllPacketsLost ||
                              baddie.packet_id == part_of_frame->packet_id));
                       }) != ignore_list_.end()) {
        return;
      }

      OnRtpPacket(*part_of_frame);
      CollectRtpPacket(*part_of_frame, std::move(packet));
    } else if (type_and_ssrc.first == ApparentPacketType::RTCP) {
      absl::optional<SenderReportParser::SenderReportWithId> report =
          sender_report_parser_.Parse(packet);
      ASSERT_TRUE(report);
      OnSenderReport(*report);
    }
  }

  std::map<FrameId, EncodedFrameWithBuffer> TakeCompleteFrames() {
    std::map<FrameId, EncodedFrameWithBuffer> result;
    result.swap(complete_frames_);
    return result;
  }

  // Tests set expectations on these mocks to monitor events of interest, and/or
  // invoke additional behaviors.
  MOCK_METHOD1(OnRtpPacket,
               void(const RtpPacketParser::ParseResult& parsed_packet));
  MOCK_METHOD1(OnFrameComplete, void(FrameId frame_id));
  MOCK_METHOD1(OnSenderReport,
               void(const SenderReportParser::SenderReportWithId& report));

 private:
  // Collects the individual RTP packets until a whole frame can be formed, then
  // calls OnFrameComplete(). Ignores extra RTP packets that are no longer
  // needed.
  void CollectRtpPacket(const RtpPacketParser::ParseResult& part_of_frame,
                        std::vector<uint8_t> packet) {
    const FrameId frame_id = part_of_frame.frame_id;
    if (complete_frames_.find(frame_id) != complete_frames_.end()) {
      return;
    }
    FrameCollector& collector = incomplete_frames_[frame_id];
    collector.set_frame_id(frame_id);
    EXPECT_TRUE(collector.CollectRtpPacket(part_of_frame, &packet));
    if (!collector.is_complete()) {
      return;
    }
    const EncryptedFrame& encrypted = collector.PeekAtAssembledFrame();
    EncodedFrameWithBuffer* const decrypted = &complete_frames_[frame_id];
    // Note: Not setting decrypted->reference_time here since the logic around
    // calculating the playout time is rather complex, and is definitely outside
    // the scope of the testing being done in this module. Instead, end-to-end
    // testing should exist elsewhere to confirm frame play-out times with real
    // Receivers.
    decrypted->buffer.resize(FrameCrypto::GetPlaintextSize(encrypted));
    decrypted->data = absl::Span<uint8_t>(decrypted->buffer);
    crypto_.Decrypt(encrypted, decrypted);
    incomplete_frames_.erase(frame_id);
    OnFrameComplete(frame_id);
  }

  SimulatedNetworkPipe* const pipe_to_sender_;
  RtcpSession rtcp_session_;
  SenderReportParser sender_report_parser_;
  CompoundRtcpBuilder rtcp_builder_;
  RtpPacketParser rtp_parser_;
  FrameCrypto crypto_;

  std::vector<PacketNack> ignore_list_;
  std::map<FrameId, FrameCollector> incomplete_frames_;
  std::map<FrameId, EncodedFrameWithBuffer> complete_frames_;
};

class MockObserver : public Sender::Observer {
 public:
  MOCK_METHOD1(OnFrameCanceled, void(FrameId frame_id));
  MOCK_METHOD0(OnPictureLost, void());
};

class SenderTest : public testing::Test {
 public:
  SenderTest()
      : fake_clock_(Clock::now()),
        task_runner_(&fake_clock_),
        sender_environment_(&FakeClock::now, &task_runner_),
        sender_packet_router_(&sender_environment_,
                              kNumPacketsPerBurst,
                              kBurstInterval),
        sender_(&sender_environment_,
                &sender_packet_router_,
                {/* .sender_ssrc = */ kSenderSsrc,
                 /* .receiver_ssrc = */ kReceiverSsrc,
                 /* .rtp_timebase = */ kRtpTimebase,
                 /* .channels = */ 2,
                 /* .target_playout_delay = */ kTargetPlayoutDelay,
                 /* .aes_secret_key = */ kAesKey,
                 /* .aes_iv_mask = */ kCastIvMask},
                kRtpPayloadType),
        receiver_to_sender_pipe_(&task_runner_, &sender_packet_router_),
        receiver_(&receiver_to_sender_pipe_),
        sender_to_receiver_pipe_(&task_runner_, &receiver_) {
    sender_environment_.set_socket_error_handler(
        [](Error error) { ASSERT_TRUE(error.ok()) << error; });
    sender_environment_.set_remote_endpoint(
        receiver_to_sender_pipe_.local_endpoint());
    ON_CALL(sender_environment_, SendPacket(_))
        .WillByDefault(Invoke([this](absl::Span<const uint8_t> packet) {
          sender_to_receiver_pipe_.StartPacketTransmission(
              std::vector<uint8_t>(packet.begin(), packet.end()));
        }));
  }

  ~SenderTest() override = default;

  Sender* sender() { return &sender_; }
  MockReceiver* receiver() { return &receiver_; }

  void SetReceiverToSenderNetworkDelay(Clock::duration delay) {
    receiver_to_sender_pipe_.set_network_delay(delay);
  }

  void SetSenderToReceiverNetworkDelay(Clock::duration delay) {
    sender_to_receiver_pipe_.set_network_delay(delay);
  }

  void SimulateExecution(Clock::duration how_long = Clock::duration::zero()) {
    fake_clock_.Advance(how_long);
  }

  static void PopulateFramePayloadBuffer(int seed,
                                         int num_bytes,
                                         std::vector<uint8_t>* payload) {
    payload->clear();
    payload->reserve(num_bytes);
    for (int i = 0; i < num_bytes; ++i) {
      payload->push_back(static_cast<uint8_t>(seed + i));
    }
  }

  static void PopulateFrameWithDefaults(FrameId frame_id,
                                        Clock::time_point reference_time,
                                        int seed,
                                        int num_payload_bytes,
                                        EncodedFrameWithBuffer* frame) {
    frame->dependency = (frame_id == FrameId::first())
                            ? EncodedFrame::KEY_FRAME
                            : EncodedFrame::DEPENDS_ON_ANOTHER;
    frame->frame_id = frame_id;
    frame->referenced_frame_id = frame->frame_id;
    if (frame_id != FrameId::first()) {
      --frame->referenced_frame_id;
    }
    frame->rtp_timestamp =
        RtpTimeTicks() + (RtpTimeDelta::FromTicks(kRtpTicksPerFrame) *
                          (frame_id - FrameId::first()));
    frame->reference_time = reference_time;
    PopulateFramePayloadBuffer(seed, num_payload_bytes, &frame->buffer);
    frame->data = absl::Span<uint8_t>(frame->buffer);
  }

  // Confirms that all |sent_frames| exist in |received_frames|, with identical
  // data and metadata.
  static void ExpectFramesReceivedCorrectly(
      absl::Span<EncodedFrameWithBuffer> sent_frames,
      const std::map<FrameId, EncodedFrameWithBuffer> received_frames) {
    ASSERT_EQ(sent_frames.size(), received_frames.size());

    for (const EncodedFrameWithBuffer& sent_frame : sent_frames) {
      SCOPED_TRACE(testing::Message()
                   << "Checking sent frame " << sent_frame.frame_id);
      const auto received_it = received_frames.find(sent_frame.frame_id);
      if (received_it == received_frames.end()) {
        ADD_FAILURE() << "Did not receive frame.";
        continue;
      }
      const EncodedFrame& received_frame = received_it->second;
      EXPECT_EQ(sent_frame.dependency, received_frame.dependency);
      EXPECT_EQ(sent_frame.referenced_frame_id,
                received_frame.referenced_frame_id);
      EXPECT_EQ(sent_frame.rtp_timestamp, received_frame.rtp_timestamp);
      EXPECT_TRUE(sent_frame.data == received_frame.data);
    }
  }

 private:
  FakeClock fake_clock_;
  FakeTaskRunner task_runner_;
  NiceMock<MockEnvironment> sender_environment_;
  SenderPacketRouter sender_packet_router_;
  Sender sender_;
  SimulatedNetworkPipe receiver_to_sender_pipe_;
  NiceMock<MockReceiver> receiver_;
  SimulatedNetworkPipe sender_to_receiver_pipe_;
};

// Tests that the Sender can send EncodedFrames over an ideal network (i.e., low
// latency, no loss), and does so without having to transmit the same packet
// twice.
TEST_F(SenderTest, SendsFramesEfficiently) {
  constexpr milliseconds kOneWayNetworkDelay{1};
  SetSenderToReceiverNetworkDelay(kOneWayNetworkDelay);
  SetReceiverToSenderNetworkDelay(kOneWayNetworkDelay);

  // Expect that each packet is only sent once.
  std::set<std::pair<FrameId, FramePacketId>> received_packets;
  EXPECT_CALL(*receiver(), OnRtpPacket(_))
      .WillRepeatedly(
          Invoke([&](const RtpPacketParser::ParseResult& parsed_packet) {
            std::pair<FrameId, FramePacketId> id(parsed_packet.frame_id,
                                                 parsed_packet.packet_id);
            const auto insert_result = received_packets.insert(id);
            EXPECT_TRUE(insert_result.second)
                << "Received duplicate packet: " << id.first << ':'
                << static_cast<int>(id.second);
          }));

  // Simulate normal frame ACK'ing behavior.
  ON_CALL(*receiver(), OnFrameComplete(_)).WillByDefault(InvokeWithoutArgs([&] {
    if (receiver()->AutoAdvanceCheckpoint()) {
      receiver()->TransmitRtcpFeedbackPacket();
    }
  }));

  NiceMock<MockObserver> observer;
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first())).Times(1);
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 1)).Times(1);
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 2)).Times(1);
  sender()->SetObserver(&observer);

  EncodedFrameWithBuffer frames[3];
  constexpr int kFrameDataSizes[] = {8196, 12, 1900};
  for (int i = 0; i < 3; ++i) {
    if (i == 0) {
      EXPECT_TRUE(sender()->NeedsKeyFrame());
    } else {
      EXPECT_FALSE(sender()->NeedsKeyFrame());
    }
    PopulateFrameWithDefaults(FrameId::first() + i,
                              FakeClock::now() - kCaptureDelay, 0xbf - i,
                              kFrameDataSizes[i], &frames[i]);
    ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
    SimulateExecution(kFrameDuration);
  }
  SimulateExecution(kTargetPlayoutDelay);

  ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
}

// Tests that the Sender correctly computes the current in-flight media
// duration, a backlog signal for clients.
TEST_F(SenderTest, ComputesInFlightMediaDuration) {
  // With no frames enqueued, the in-flight media duration should be zero.
  EXPECT_EQ(Clock::duration::zero(),
            sender()->GetInFlightMediaDuration(RtpTimeTicks()));
  EXPECT_EQ(Clock::duration::zero(),
            sender()->GetInFlightMediaDuration(
                RtpTimeTicks() + RtpTimeDelta::FromTicks(kRtpTicksPerFrame)));

  // Enqueue a frame.
  EncodedFrameWithBuffer frame;
  PopulateFrameWithDefaults(FrameId::first(), FakeClock::now(), 0,
                            13 /* bytes */, &frame);
  ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));

  // Now, the in-flight media duration should depend on the RTP timestamp of the
  // next frame.
  EXPECT_EQ(kFrameDuration, sender()->GetInFlightMediaDuration(
                                frame.rtp_timestamp +
                                RtpTimeDelta::FromTicks(kRtpTicksPerFrame)));
  EXPECT_EQ(10 * kFrameDuration,
            sender()->GetInFlightMediaDuration(
                frame.rtp_timestamp +
                RtpTimeDelta::FromTicks(10 * kRtpTicksPerFrame)));
}

// Tests that the Sender computes the maximum in-flight media duration based on
// its analysis of current network conditions. By implication, this demonstrates
// that the Sender is also measuring the network round-trip time.
TEST_F(SenderTest, RespondsToNetworkLatencyChanges) {
  // The expected maximum error in time calculations is one tick of the RTCP
  // report block's delay type.
  constexpr auto kEpsilon = to_nanoseconds(RtcpReportBlock::Delay(1));

  // Before the Sender has the necessary information to compute the network
  // round-trip time, GetMaxInFlightMediaDuration() will return half the target
  // playout delay.
  EXPECT_NEARLY_EQUAL(kTargetPlayoutDelay / 2,
                      sender()->GetMaxInFlightMediaDuration(), kEpsilon);

  // No network is perfect. Simulate different one-way network delays.
  constexpr milliseconds kOutboundDelay{2};
  constexpr milliseconds kInboundDelay{4};
  constexpr milliseconds kRoundTripDelay = kOutboundDelay + kInboundDelay;
  SetSenderToReceiverNetworkDelay(kOutboundDelay);
  SetReceiverToSenderNetworkDelay(kInboundDelay);

  // Enqueue a frame in the Sender to start emitting periodic RTCP reports.
  {
    EncodedFrameWithBuffer frame;
    PopulateFrameWithDefaults(FrameId::first(), FakeClock::now(), 0,
                              1 /* byte */, &frame);
    ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
  }

  // Run one network round-trip from Sender→Receiver→Sender.
  StatusReportId sender_report_id{};
  EXPECT_CALL(*receiver(), OnSenderReport(_))
      .WillOnce(Invoke(
          [&](const SenderReportParser::SenderReportWithId& sender_report) {
            sender_report_id = sender_report.report_id;
          }));
  // Simulate the passage of time for the Sender Report to reach the Receiver.
  SimulateExecution(kOutboundDelay);
  // The Receiver should have received the Sender Report at this point.
  Mock::VerifyAndClearExpectations(receiver());
  ASSERT_NE(StatusReportId{}, sender_report_id);
  // Simulate the passage of time in the Receiver doing "other tasks" before
  // replying back to the Sender. This delay is included in the Receiver Report
  // so that the Sender can isolate the delays caused by the network.
  constexpr milliseconds kReceiverProcessingDelay{2};
  SimulateExecution(kReceiverProcessingDelay);
  // Create the Receiver Report "reply," and simulate it being sent across the
  // network, back to the Sender.
  receiver()->SetReceiverReport(
      sender_report_id, std::chrono::duration_cast<RtcpReportBlock::Delay>(
                            kReceiverProcessingDelay));
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution(kInboundDelay);

  // At this point, the Sender should have computed the network round-trip time,
  // and so GetMaxInFlightMediaDuration() will return half the target playout
  // delay PLUS half the network round-trip time.
  EXPECT_NEARLY_EQUAL(kTargetPlayoutDelay / 2 + kRoundTripDelay / 2,
                      sender()->GetMaxInFlightMediaDuration(), kEpsilon);

  // Increase the outbound delay, which will increase the total round-trip time.
  constexpr milliseconds kIncreasedOutboundDelay{6};
  constexpr milliseconds kIncreasedRoundTripDelay =
      kIncreasedOutboundDelay + kInboundDelay;
  SetSenderToReceiverNetworkDelay(kIncreasedOutboundDelay);

  // With increased network delay, run several more network round-trips. Expect
  // the Sender to gradually converge towards the new network round-trip time.
  constexpr int kNumReportIntervals = 50;
  EXPECT_CALL(*receiver(), OnSenderReport(_))
      .Times(kNumReportIntervals)
      .WillRepeatedly(Invoke(
          [&](const SenderReportParser::SenderReportWithId& sender_report) {
            receiver()->SetReceiverReport(sender_report.report_id,
                                          RtcpReportBlock::Delay::zero());
            receiver()->TransmitRtcpFeedbackPacket();
          }));
  Clock::duration last_max = sender()->GetMaxInFlightMediaDuration();
  for (int i = 0; i < kNumReportIntervals; ++i) {
    SimulateExecution(kRtcpReportInterval);
    const Clock::duration updated_value =
        sender()->GetMaxInFlightMediaDuration();
    EXPECT_LE(last_max, updated_value);
    last_max = updated_value;
  }
  EXPECT_NEARLY_EQUAL(kTargetPlayoutDelay / 2 + kIncreasedRoundTripDelay / 2,
                      sender()->GetMaxInFlightMediaDuration(), kEpsilon);
}

// Tests that the Sender rejects frames if too large a span of FrameIds would be
// in-flight at once.
TEST_F(SenderTest, RejectsEnqueuingBeforeProtocolDesignLimit) {
  // For this test, use 1000 FPS. This makes the frames all one millisecond
  // apart to avoid triggering the media-duration rejection logic.
  constexpr int kFramesPerSecond = 1000;
  constexpr milliseconds kFrameDuration{1};

  const auto OverrideRtpTimestamp = [](int frame_count, EncodedFrame* frame) {
    const int ticks = frame_count * kRtpTimebase / kFramesPerSecond;
    frame->rtp_timestamp = RtpTimeTicks() + RtpTimeDelta::FromTicks(ticks);
  };

  // Send the absolute design-limit maximum number of frames.
  int frame_count = 0;
  for (; frame_count < kMaxUnackedFrames; ++frame_count) {
    EncodedFrameWithBuffer frame;
    PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
                              13 /* bytes */, &frame);
    OverrideRtpTimestamp(frame_count, &frame);
    ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
    SimulateExecution(kFrameDuration);
  }

  // Now, attempting to enqueue just one more frame should fail.
  EncodedFrameWithBuffer one_frame_too_much;
  PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
                            13 /* bytes */, &one_frame_too_much);
  OverrideRtpTimestamp(frame_count++, &one_frame_too_much);
  EXPECT_EQ(Sender::REACHED_ID_SPAN_LIMIT,
            sender()->EnqueueFrame(one_frame_too_much));
  SimulateExecution(kFrameDuration);

  // Now, simulate the Receiver ACKing the first frame, and enqueuing should
  // then succeed again.
  receiver()->SetCheckpointFrame(FrameId::first());
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.
  EXPECT_EQ(Sender::OK, sender()->EnqueueFrame(one_frame_too_much));
  SimulateExecution(kFrameDuration);

  // Finally, attempting to enqueue another frame should fail again.
  EncodedFrameWithBuffer another_frame_too_much;
  PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
                            13 /* bytes */, &another_frame_too_much);
  OverrideRtpTimestamp(frame_count++, &another_frame_too_much);
  EXPECT_EQ(Sender::REACHED_ID_SPAN_LIMIT,
            sender()->EnqueueFrame(another_frame_too_much));
  SimulateExecution(kFrameDuration);
}

// Tests that the Sender rejects frames if too-long a media duration is
// in-flight. This is the Sender's primary flow control mechanism.
TEST_F(SenderTest, RejectsEnqueuingIfTooLongMediaDurationIsInFlight) {
  // For this test, use 20 FPS. This makes all frames 50 ms apart, which should
  // make it easy to trigger the media-duration rejection logic.
  constexpr int kFramesPerSecond = 20;
  constexpr milliseconds kFrameDuration{50};

  const auto OverrideRtpTimestamp = [](int frame_count, EncodedFrame* frame) {
    const int ticks = frame_count * kRtpTimebase / kFramesPerSecond;
    frame->rtp_timestamp = RtpTimeTicks() + RtpTimeDelta::FromTicks(ticks);
  };

  // Enqueue frames until one is rejected because the in-flight duration would
  // be too high.
  EncodedFrameWithBuffer frame;
  int frame_count = 0;
  for (; frame_count < kMaxUnackedFrames; ++frame_count) {
    PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
                              13 /* bytes */, &frame);
    OverrideRtpTimestamp(frame_count, &frame);
    const auto result = sender()->EnqueueFrame(frame);
    SimulateExecution(kFrameDuration);
    if (result == Sender::MAX_DURATION_IN_FLIGHT) {
      break;
    }
    ASSERT_EQ(Sender::OK, result);
  }

  // Now, simulate the Receiver ACKing the first frame, and enqueuing should
  // then succeed again.
  receiver()->SetCheckpointFrame(FrameId::first());
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.
  EXPECT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
  SimulateExecution(kFrameDuration);

  // However, attempting to enqueue another frame should fail again.
  EncodedFrameWithBuffer one_frame_too_much;
  PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
                            13 /* bytes */, &one_frame_too_much);
  OverrideRtpTimestamp(++frame_count, &one_frame_too_much);
  EXPECT_EQ(Sender::MAX_DURATION_IN_FLIGHT,
            sender()->EnqueueFrame(one_frame_too_much));
  SimulateExecution(kFrameDuration);
}

// Tests that the Sender propagates the Receiver's picture loss indicator to the
// Observer::OnPictureLost(), and via calls to NeedsKeyFrame(); but only when
// producing a key frame is absolutely necessary.
TEST_F(SenderTest, ManagesReceiverPictureLossWorkflow) {
  NiceMock<MockObserver> observer;
  sender()->SetObserver(&observer);

  // Send three frames...
  EncodedFrameWithBuffer frames[6];
  for (int i = 0; i < 3; ++i) {
    if (i == 0) {
      EXPECT_TRUE(sender()->NeedsKeyFrame());
    } else {
      EXPECT_FALSE(sender()->NeedsKeyFrame());
    }
    PopulateFrameWithDefaults(FrameId::first() + i,
                              FakeClock::now() - kCaptureDelay, 0,
                              24 /* bytes */, &frames[i]);
    ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
    SimulateExecution(kFrameDuration);
  }
  SimulateExecution(kTargetPlayoutDelay);

  // Simulate the Receiver ACK'ing the first three frames.
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first())).Times(1);
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 1)).Times(1);
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 2)).Times(1);
  EXPECT_CALL(observer, OnPictureLost()).Times(0);
  receiver()->SetCheckpointFrame(frames[2].frame_id);
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.
  Mock::VerifyAndClearExpectations(&observer);

  // Simulate something going wrong in the Receiver, and have it report picture
  // loss to the Sender. The Sender should then propagate this to its Observer
  // and return true when NeedsKeyFrame() is called.
  EXPECT_CALL(observer, OnFrameCanceled(_)).Times(0);
  EXPECT_CALL(observer, OnPictureLost()).Times(1);
  EXPECT_FALSE(sender()->NeedsKeyFrame());
  receiver()->SetPictureLossIndicator(true);
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_TRUE(sender()->NeedsKeyFrame());

  // Send a non-key frame, and expect NeedsKeyFrame() still returns true. The
  // Observer is not re-notified. This accounts for the case where a client's
  // media encoder had frames in its processing pipeline before NeedsKeyFrame()
  // began returning true.
  EXPECT_CALL(observer, OnFrameCanceled(_)).Times(0);
  EXPECT_CALL(observer, OnPictureLost()).Times(0);
  EncodedFrameWithBuffer& nonkey_frame = frames[3];
  PopulateFrameWithDefaults(FrameId::first() + 3,
                            FakeClock::now() - kCaptureDelay, 0, 24 /* bytes */,
                            &nonkey_frame);
  ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(nonkey_frame));
  SimulateExecution(kFrameDuration);
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_TRUE(sender()->NeedsKeyFrame());

  // Now send a key frame, and expect NeedsKeyFrame() returns false. Note that
  // the Receiver hasn't cleared the PLI condition, but the Sender knows more
  // key frames won't be needed.
  EXPECT_CALL(observer, OnFrameCanceled(_)).Times(0);
  EXPECT_CALL(observer, OnPictureLost()).Times(0);
  EncodedFrameWithBuffer& recovery_frame = frames[4];
  PopulateFrameWithDefaults(FrameId::first() + 4,
                            FakeClock::now() - kCaptureDelay, 0, 24 /* bytes */,
                            &recovery_frame);
  recovery_frame.dependency = EncodedFrame::KEY_FRAME;
  recovery_frame.referenced_frame_id = recovery_frame.frame_id;
  ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(recovery_frame));
  SimulateExecution(kFrameDuration);
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_FALSE(sender()->NeedsKeyFrame());

  // Let's say the Receiver hasn't received the key frame yet, and it reports
  // its picture loss again to the Sender. Observer::OnPictureLost() should not
  // be called, and NeedsKeyFrame() should NOT return true, because the Sender
  // knows the Receiver hasn't acknowledged the key frame (just sent) yet.
  EXPECT_CALL(observer, OnFrameCanceled(nonkey_frame.frame_id)).Times(1);
  EXPECT_CALL(observer, OnPictureLost()).Times(0);
  receiver()->SetCheckpointFrame(nonkey_frame.frame_id);
  receiver()->SetPictureLossIndicator(true);
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_FALSE(sender()->NeedsKeyFrame());

  // Now, simulate the Receiver getting the key frame, but NOT recovering. This
  // should cause Observer::OnPictureLost() to be called, and cause
  // NeedsKeyFrame() to return true again.
  EXPECT_CALL(observer, OnFrameCanceled(recovery_frame.frame_id)).Times(1);
  EXPECT_CALL(observer, OnPictureLost()).Times(1);
  receiver()->SetCheckpointFrame(recovery_frame.frame_id);
  receiver()->SetPictureLossIndicator(true);
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_TRUE(sender()->NeedsKeyFrame());

  // Send another key frame, and expect NeedsKeyFrame() returns false.
  EXPECT_CALL(observer, OnFrameCanceled(_)).Times(0);
  EXPECT_CALL(observer, OnPictureLost()).Times(0);
  EncodedFrameWithBuffer& another_recovery_frame = frames[5];
  PopulateFrameWithDefaults(FrameId::first() + 5,
                            FakeClock::now() - kCaptureDelay, 0, 24 /* bytes */,
                            &another_recovery_frame);
  another_recovery_frame.dependency = EncodedFrame::KEY_FRAME;
  another_recovery_frame.referenced_frame_id = another_recovery_frame.frame_id;
  ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(another_recovery_frame));
  SimulateExecution(kFrameDuration);
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_FALSE(sender()->NeedsKeyFrame());

  // Now, simulate the Receiver recovering. It will report this to the Sender,
  // and NeedsKeyFrame() will still return false.
  EXPECT_CALL(observer, OnFrameCanceled(another_recovery_frame.frame_id))
      .Times(1);
  EXPECT_CALL(observer, OnPictureLost()).Times(0);
  receiver()->SetCheckpointFrame(another_recovery_frame.frame_id);
  receiver()->SetPictureLossIndicator(false);
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.
  Mock::VerifyAndClearExpectations(&observer);
  EXPECT_FALSE(sender()->NeedsKeyFrame());

  ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
}

// Tests that the Receiver should get a Sender Report just before the first RTP
// packet, and at regular intervals thereafter. The Sender Report contains the
// lip-sync information necessary for play-out timing.
TEST_F(SenderTest, ProvidesSenderReports) {
  std::vector<SenderReportParser::SenderReportWithId> sender_reports;
  Sequence packet_sequence;
  EXPECT_CALL(*receiver(), OnSenderReport(_))
      .InSequence(packet_sequence)
      .WillOnce(
          Invoke([&](const SenderReportParser::SenderReportWithId& report) {
            sender_reports.push_back(report);
          }))
      .RetiresOnSaturation();
  EXPECT_CALL(*receiver(), OnRtpPacket(_)).Times(1).InSequence(packet_sequence);
  EXPECT_CALL(*receiver(), OnSenderReport(_))
      .Times(3)
      .InSequence(packet_sequence)
      .WillRepeatedly(
          Invoke([&](const SenderReportParser::SenderReportWithId& report) {
            sender_reports.push_back(report);
          }));

  EncodedFrameWithBuffer frame;
  constexpr int kFrameDataSize = 250;
  PopulateFrameWithDefaults(FrameId::first(), FakeClock::now(), 0,
                            kFrameDataSize, &frame);
  ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
  SimulateExecution();  // Should send one Sender Report + one RTP packet.
  EXPECT_EQ(size_t{1}, sender_reports.size());

  // Have the Receiver ACK the frame to prevent retransmitting the RTP packet.
  receiver()->SetCheckpointFrame(FrameId::first());
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.

  // Advance through three more reporting intervals. One Sender Report should be
  // sent each interval, making a total of 4 reports sent.
  constexpr auto kThreeReportIntervals = 3 * kRtcpReportInterval;
  SimulateExecution(kThreeReportIntervals);  // Three more Sender Reports.
  ASSERT_EQ(size_t{4}, sender_reports.size());

  // The first report should contain the same timestamps as the frame because
  // the Clock did not advance. Also, its packet count and octet count fields
  // should be zero since the report was sent before the RTP packet.
  EXPECT_EQ(frame.reference_time, sender_reports.front().reference_time);
  EXPECT_EQ(frame.rtp_timestamp, sender_reports.front().rtp_timestamp);
  EXPECT_EQ(uint32_t{0}, sender_reports.front().send_packet_count);
  EXPECT_EQ(uint32_t{0}, sender_reports.front().send_octet_count);

  // The last report should contain the timestamps extrapolated into the future
  // because the Clock did move forward. Also, the packet count and octet fields
  // should now be non-zero because the report was sent after the RTP packet.
  EXPECT_EQ(frame.reference_time + kThreeReportIntervals,
            sender_reports.back().reference_time);
  EXPECT_EQ(frame.rtp_timestamp +
                RtpTimeDelta::FromDuration(kThreeReportIntervals, kRtpTimebase),
            sender_reports.back().rtp_timestamp);
  EXPECT_EQ(uint32_t{1}, sender_reports.back().send_packet_count);
  EXPECT_EQ(uint32_t{kFrameDataSize}, sender_reports.back().send_octet_count);
}

// Tests that the Sender provides Kickstart packets whenever the Receiver may
// not know about new frames.
TEST_F(SenderTest, ProvidesKickstartPacketsIfReceiverDoesNotACK) {
  // Have the Receiver move the checkpoint forward only for the first frame, and
  // none of the later frames. This will force the Sender to eventually send a
  // Kickstart packet.
  ON_CALL(*receiver(), OnFrameComplete(_))
      .WillByDefault(Invoke([&](FrameId frame_id) {
        if (frame_id == FrameId::first()) {
          receiver()->SetCheckpointFrame(FrameId::first());
          receiver()->TransmitRtcpFeedbackPacket();
        }
      }));

  // Send three frames, paced to the media.
  EncodedFrameWithBuffer frames[3];
  for (int i = 0; i < 3; ++i) {
    PopulateFrameWithDefaults(FrameId::first() + i,
                              FakeClock::now() - kCaptureDelay, i,
                              48 /* bytes */, &frames[i]);
    ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
    SimulateExecution(kFrameDuration);
  }

  // Now, do nothing for a while. Because the Receiver isn't moving the
  // checkpoint forward, the Sender will have sent all the RTP packets at least
  // once, and then will start sending just Kickstart packets.
  SimulateExecution(kTargetPlayoutDelay);

  // Keep doing nothing for a while, and confirm the Sender is just sending the
  // same Kickstart packet over and over. The Kickstart packet is supposed to be
  // the last packet of the latest frame.
  std::set<std::pair<FrameId, FramePacketId>> unique_received_packet_ids;
  EXPECT_CALL(*receiver(), OnRtpPacket(_))
      .WillRepeatedly(
          Invoke([&](const RtpPacketParser::ParseResult& parsed_packet) {
            unique_received_packet_ids.emplace(parsed_packet.frame_id,
                                               parsed_packet.packet_id);
          }));
  SimulateExecution(kTargetPlayoutDelay);
  Mock::VerifyAndClearExpectations(receiver());
  EXPECT_EQ(size_t{1}, unique_received_packet_ids.size());
  EXPECT_EQ(frames[2].frame_id, unique_received_packet_ids.begin()->first);

  // Now, simulate the Receiver ACKing all the frames.
  receiver()->SetCheckpointFrame(frames[2].frame_id);
  receiver()->TransmitRtcpFeedbackPacket();
  SimulateExecution();  // RTCP transmitted to Sender.

  // With all the frames sent, the Sender should not be transmitting anything.
  EXPECT_CALL(*receiver(), OnRtpPacket(_)).Times(0);
  SimulateExecution(10 * kTargetPlayoutDelay);

  ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
}

// Tests that the Sender only retransmits packets specifically NACK'ed by the
// Receiver.
TEST_F(SenderTest, ResendsIndividuallyNackedPackets) {
  // Populate the frame data in each frame with enough bytes to force at least
  // three RTP packets per frame.
  constexpr int kFrameDataSize = 3 * kMaxRtpPacketSizeForIpv6UdpOnEthernet;

  // Use a 1ms network delay in each direction to make the sequence of events
  // clearer in this test.
  constexpr milliseconds kOneWayNetworkDelay{1};
  SetSenderToReceiverNetworkDelay(kOneWayNetworkDelay);
  SetReceiverToSenderNetworkDelay(kOneWayNetworkDelay);

  // Simulate that three specific packets will be dropped by the network, one
  // from each frame (about to be sent).
  const std::vector<PacketNack> dropped_packets{
      {FrameId::first(), FramePacketId{2}},
      {FrameId::first() + 1, FramePacketId{1}},
      {FrameId::first() + 2, FramePacketId{0}},
  };
  receiver()->SetIgnoreList(dropped_packets);

  // Send three frames, paced to the media. The Receiver won't completely
  // receive any of these frames due to dropped packets.
  EXPECT_CALL(*receiver(), OnFrameComplete(_)).Times(0);
  EncodedFrameWithBuffer frames[3];
  for (int i = 0; i < 3; ++i) {
    PopulateFrameWithDefaults(FrameId::first() + i,
                              FakeClock::now() - kCaptureDelay, i,
                              kFrameDataSize, &frames[i]);
    ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
    SimulateExecution(kFrameDuration);
  }
  SimulateExecution(kTargetPlayoutDelay);
  Mock::VerifyAndClearExpectations(receiver());
  EXPECT_EQ(3, sender()->GetInFlightFrameCount());

  // The Receiver NACKs the three dropped packets...
  receiver()->SetNacksAndAcks(dropped_packets, {});
  receiver()->TransmitRtcpFeedbackPacket();

  // In the meantime, the network recovers (i.e., no more dropped packets)...
  receiver()->SetIgnoreList({});

  // The NACKs reach the Sender, and it acts on them by retransmitting.
  SimulateExecution(kOneWayNetworkDelay);

  // As each retransmitted packet arrives at the Receiver, advance the
  // checkpoint forward to notify the Sender of frames that are now completely
  // received. Also, confirm that only the three specifically-NACK'ed packets
  // were retransmitted.
  EXPECT_CALL(*receiver(), OnFrameComplete(_))
      .Times(3)
      .WillRepeatedly(InvokeWithoutArgs([&] {
        if (receiver()->AutoAdvanceCheckpoint()) {
          receiver()->TransmitRtcpFeedbackPacket();
        }
      }));
  EXPECT_CALL(*receiver(), OnRtpPacket(_))
      .Times(3)
      .WillRepeatedly(Invoke([&](const RtpPacketParser::ParseResult& packet) {
        EXPECT_FALSE(std::find(dropped_packets.begin(), dropped_packets.end(),
                               PacketNack{packet.frame_id, packet.packet_id}) ==
                     dropped_packets.end());
      }));
  SimulateExecution(kOneWayNetworkDelay);
  Mock::VerifyAndClearExpectations(receiver());

  // The Receiver checkpoint feedback(s) travel back to the Sender, and there
  // should no longer be any frames in-flight.
  SimulateExecution(kOneWayNetworkDelay);
  EXPECT_EQ(0, sender()->GetInFlightFrameCount());

  // The Sender should not be transmitting anything from now on since all frames
  // are known to have been completely received.
  EXPECT_CALL(*receiver(), OnRtpPacket(_)).Times(0);
  SimulateExecution(10 * kTargetPlayoutDelay);

  ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
}

// Tests that the Sender retransmits an entire frame if the Receiver requests it
// (i.e., a full frame NACK), but does not retransmit any packets for frames
// (before or after) that have been acknowledged.
TEST_F(SenderTest, ResendsMissingFrames) {
  // Populate the frame data in each frame with enough bytes to force at least
  // three RTP packets per frame.
  constexpr int kFrameDataSize = 3 * kMaxRtpPacketSizeForIpv6UdpOnEthernet;

  // Use a 1ms network delay in each direction to make the sequence of events
  // clearer in this test.
  constexpr milliseconds kOneWayNetworkDelay{1};
  SetSenderToReceiverNetworkDelay(kOneWayNetworkDelay);
  SetReceiverToSenderNetworkDelay(kOneWayNetworkDelay);

  // Simulate that all of the packets for the second frame will be dropped by
  // the network, but only the packets for that frame.
  const std::vector<PacketNack> dropped_packets{
      {FrameId::first() + 1, kAllPacketsLost},
  };
  receiver()->SetIgnoreList(dropped_packets);

  NiceMock<MockObserver> observer;
  sender()->SetObserver(&observer);

  // The expectations below track the story and execute simulated Receiver
  // responses. The Sender will have three frames enqueued by its client, and
  // then...
  //
  // The first frame is received and the Receiver ACKs it by moving the
  // checkpoint forward.
  Sequence completion_sequence;
  EXPECT_CALL(*receiver(), OnFrameComplete(FrameId::first()))
      .InSequence(completion_sequence)
      .WillOnce(InvokeWithoutArgs([&] {
        receiver()->SetCheckpointFrame(FrameId::first());
        receiver()->TransmitRtcpFeedbackPacket();
      }));
  // Since all of the packets for the second frame are being dropped, the third
  // frame will finish next. The Receiver responds by NACKing the second frame
  // and ACKing the third frame. The checkpoint does not move forward because
  // the second frame has not been received yet.
  //
  // NETWORK CHANGE: After the third frame is received, stop dropping packets.
  EXPECT_CALL(*receiver(), OnFrameComplete(FrameId::first() + 2))
      .InSequence(completion_sequence)
      .WillOnce(InvokeWithoutArgs([&] {
        receiver()->SetNacksAndAcks(dropped_packets,
                                    std::vector<FrameId>{FrameId::first() + 2});
        receiver()->TransmitRtcpFeedbackPacket();
        receiver()->SetIgnoreList({});
      }));
  // Finally, the Sender should respond to the whole-frame NACK by re-sending
  // all of the packets for the second frame, and so the Receiver should
  // completely receive the frame.
  EXPECT_CALL(*receiver(), OnFrameComplete(FrameId::first() + 1))
      .InSequence(completion_sequence)
      .WillOnce(InvokeWithoutArgs([&] {
        receiver()->SetCheckpointFrame(FrameId::first() + 2);
        receiver()->TransmitRtcpFeedbackPacket();
      }));

  // From the Sender's perspective, the Receiver will ACK the first frame, then
  // the third frame, then the second frame.
  Sequence cancel_sequence;
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first()))
      .Times(1)
      .InSequence(cancel_sequence);
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 2))
      .Times(1)
      .InSequence(cancel_sequence);
  EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 1))
      .Times(1)
      .InSequence(cancel_sequence);

  // With all the expectations/sequences in-place, let 'er rip!
  EncodedFrameWithBuffer frames[3];
  for (int i = 0; i < 3; ++i) {
    PopulateFrameWithDefaults(FrameId::first() + i,
                              FakeClock::now() - kCaptureDelay, i,
                              kFrameDataSize, &frames[i]);
    ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
    SimulateExecution(kFrameDuration);
  }
  SimulateExecution(kTargetPlayoutDelay);
  Mock::VerifyAndClearExpectations(receiver());
  EXPECT_EQ(0, sender()->GetInFlightFrameCount());

  // The Sender should not be transmitting anything from now on since all frames
  // are known to have been completely received.
  EXPECT_CALL(*receiver(), OnRtpPacket(_)).Times(0);
  SimulateExecution(10 * kTargetPlayoutDelay);

  ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
}

}  // namespace
}  // namespace cast
}  // namespace openscreen
