// Copyright 2019 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/receiver.h"

#include <stdint.h>

#include <algorithm>
#include <array>
#include <utility>
#include <vector>

#include "absl/types/span.h"
#include "cast/streaming/compound_rtcp_parser.h"
#include "cast/streaming/constants.h"
#include "cast/streaming/encoded_frame.h"
#include "cast/streaming/frame_crypto.h"
#include "cast/streaming/mock_environment.h"
#include "cast/streaming/receiver_packet_router.h"
#include "cast/streaming/rtcp_common.h"
#include "cast/streaming/rtcp_session.h"
#include "cast/streaming/rtp_defines.h"
#include "cast/streaming/rtp_packetizer.h"
#include "cast/streaming/rtp_time.h"
#include "cast/streaming/sender_report_builder.h"
#include "cast/streaming/session_config.h"
#include "cast/streaming/ssrc.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "platform/api/time.h"
#include "platform/api/udp_socket.h"
#include "platform/base/error.h"
#include "platform/base/ip_address.h"
#include "platform/base/udp_packet.h"
#include "platform/test/fake_clock.h"
#include "platform/test/fake_task_runner.h"
#include "util/chrono_helpers.h"
#include "util/osp_logging.h"

using testing::_;
using testing::AtLeast;
using testing::Gt;
using testing::Invoke;
using testing::SaveArg;

namespace openscreen {
namespace cast {
namespace {

// Receiver configuration.

constexpr Ssrc kSenderSsrc = 1;
constexpr Ssrc kReceiverSsrc = 2;
constexpr int kRtpTimebase = 48000;
constexpr milliseconds kTargetPlayoutDelay{100};
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 milliseconds kTargetPlayoutDelayChange{800};
// Additional configuration for the Sender.
constexpr RtpPayloadType kRtpPayloadType = RtpPayloadType::kVideoVp8;
constexpr int kMaxRtpPacketSize = 64;

// A simulated one-way network delay, and round-trip network delay.
constexpr auto kOneWayNetworkDelay = milliseconds(3);
constexpr auto kRoundTripNetworkDelay = 2 * kOneWayNetworkDelay;
static_assert(kRoundTripNetworkDelay < kTargetPlayoutDelay &&
                  kRoundTripNetworkDelay < kTargetPlayoutDelayChange,
              "Network delay must be smaller than target playout delay.");

// An EncodedFrame for unit testing, one of a sequence of simulated frames, each
// of 10 ms duration. The first frame will be a key frame; and any later frames
// will be non-key, dependent on the prior frame. Frame 5 (the 6th frame in the
// zero-based sequence) will include a target playout delay change, an increase
// to 800 ms. Frames with different IDs will contain vary in their payload data
// size, but are always 3 or more packets' worth of data.
struct SimulatedFrame : public EncodedFrame {
  static constexpr milliseconds kFrameDuration = milliseconds(10);
  static constexpr milliseconds kTargetPlayoutDelayChange = milliseconds(800);

  static constexpr int kPlayoutChangeAtFrame = 5;

  SimulatedFrame(Clock::time_point first_frame_reference_time, int which) {
    frame_id = FrameId::first() + which;
    if (which == 0) {
      dependency = EncodedFrame::KEY_FRAME;
      referenced_frame_id = frame_id;
    } else {
      dependency = EncodedFrame::DEPENDS_ON_ANOTHER;
      referenced_frame_id = frame_id - 1;
    }
    rtp_timestamp =
        GetRtpStartTime() +
        RtpTimeDelta::FromDuration(kFrameDuration * which, kRtpTimebase);
    reference_time = first_frame_reference_time + kFrameDuration * which;
    if (which == kPlayoutChangeAtFrame) {
      new_playout_delay = kTargetPlayoutDelayChange;
    }
    constexpr int kAdditionalBytesEachSuccessiveFrame = 3;
    buffer_.resize(3 * kMaxRtpPacketSize +
                   which * kAdditionalBytesEachSuccessiveFrame);
    for (size_t i = 0; i < buffer_.size(); ++i) {
      buffer_[i] = static_cast<uint8_t>(which + static_cast<int>(i));
    }
    data = absl::Span<uint8_t>(buffer_);
  }

  static RtpTimeTicks GetRtpStartTime() {
    return RtpTimeTicks::FromTimeSinceOrigin(seconds(0), kRtpTimebase);
  }

  static milliseconds GetExpectedPlayoutDelay(int which) {
    return (which < kPlayoutChangeAtFrame) ? kTargetPlayoutDelay
                                           : kTargetPlayoutDelayChange;
  }

 private:
  std::vector<uint8_t> buffer_;
};

// static
constexpr milliseconds SimulatedFrame::kFrameDuration;
constexpr milliseconds SimulatedFrame::kTargetPlayoutDelayChange;
constexpr int SimulatedFrame::kPlayoutChangeAtFrame;

// Processes packets from the Receiver under test, as a real Sender might, and
// allows the unit tests to set expectations on events of interest to confirm
// proper behavior of the Receiver.
class MockSender : public CompoundRtcpParser::Client {
 public:
  MockSender(TaskRunner* task_runner, UdpSocket::Client* receiver)
      : task_runner_(task_runner),
        receiver_(receiver),
        sender_endpoint_{
            // Use a random IPv6 address in the range reserved for
            // "documentation purposes." Thus, the following is a fake address
            // that should be blocked by the OS (and all network packet
            // routers). But, these tests don't use real sockets, so...
            IPAddress::Parse("2001:db8:0d93:69c2:fd1a:49a6:a7c0:e8a6").value(),
            2344},
        rtcp_session_(kSenderSsrc, kReceiverSsrc, FakeClock::now()),
        sender_report_builder_(&rtcp_session_),
        rtcp_parser_(&rtcp_session_, this),
        crypto_(kAesKey, kCastIvMask),
        rtp_packetizer_(kRtpPayloadType, kSenderSsrc, kMaxRtpPacketSize) {}

  ~MockSender() override = default;

  void set_max_feedback_frame_id(FrameId f) { max_feedback_frame_id_ = f; }

  // Called by the test procedures to generate a Sender Report containing the
  // given lip-sync timestamps, and send it to the Receiver. The caller must
  // spin the TaskRunner for the RTCP packet to be delivered to the Receiver.
  StatusReportId SendSenderReport(Clock::time_point reference_time,
                                  RtpTimeTicks rtp_timestamp) {
    // Generate the Sender Report RTCP packet.
    uint8_t buffer[kMaxRtpPacketSizeForIpv4UdpOnEthernet];
    RtcpSenderReport sender_report;
    sender_report.reference_time = reference_time;
    sender_report.rtp_timestamp = rtp_timestamp;
    const auto packet_and_report_id =
        sender_report_builder_.BuildPacket(sender_report, buffer);

    // Send the RTCP packet as a UdpPacket directly to the Receiver instance.
    UdpPacket packet_to_send(packet_and_report_id.first.begin(),
                             packet_and_report_id.first.end());
    packet_to_send.set_source(sender_endpoint_);
    task_runner_->PostTaskWithDelay(
        [receiver = receiver_, packet = std::move(packet_to_send)]() mutable {
          receiver->OnRead(nullptr, ErrorOr<UdpPacket>(std::move(packet)));
        },
        kOneWayNetworkDelay);

    return packet_and_report_id.second;
  }

  // Sets which frame is currently being sent by this MockSender. Test code must
  // call SendRtpPackets() to send the packets.
  void SetFrameBeingSent(const EncodedFrame& frame) {
    frame_being_sent_ = crypto_.Encrypt(frame);
  }

  // Returns a vector containing each packet ID once (of the current frame being
  // sent). |permutation| controls the sort order of the vector: zero will
  // provide all the packet IDs in order, and greater values will provide them
  // in a different, predictable order.
  std::vector<FramePacketId> GetAllPacketIds(int permutation) {
    const int num_packets =
        rtp_packetizer_.ComputeNumberOfPackets(frame_being_sent_);
    OSP_CHECK_GT(num_packets, 0);
    std::vector<FramePacketId> ids;
    ids.reserve(num_packets);
    const FramePacketId last_packet_id =
        static_cast<FramePacketId>(num_packets - 1);
    for (FramePacketId packet_id = 0; packet_id <= last_packet_id;
         ++packet_id) {
      ids.push_back(packet_id);
    }
    for (int i = 0; i < permutation; ++i) {
      std::next_permutation(ids.begin(), ids.end());
    }
    return ids;
  }

  // Send the specified packets of the current frame being sent.
  void SendRtpPackets(const std::vector<FramePacketId>& packets_to_send) {
    uint8_t buffer[kMaxRtpPacketSize];
    for (FramePacketId packet_id : packets_to_send) {
      const auto span =
          rtp_packetizer_.GeneratePacket(frame_being_sent_, packet_id, buffer);
      UdpPacket packet_to_send(span.begin(), span.end());
      packet_to_send.set_source(sender_endpoint_);
      task_runner_->PostTaskWithDelay(
          [receiver = receiver_, packet = std::move(packet_to_send)]() mutable {
            receiver->OnRead(nullptr, ErrorOr<UdpPacket>(std::move(packet)));
          },
          kOneWayNetworkDelay);
    }
  }

  // Called to process a packet from the Receiver.
  void OnPacketFromReceiver(absl::Span<const uint8_t> packet) {
    EXPECT_TRUE(rtcp_parser_.Parse(packet, max_feedback_frame_id_));
  }

  // CompoundRtcpParser::Client implementation: Tests set expectations on these
  // mocks to confirm that the receiver is providing the right data to the
  // sender in its RTCP packets.
  MOCK_METHOD1(OnReceiverReferenceTimeAdvanced,
               void(Clock::time_point reference_time));
  MOCK_METHOD1(OnReceiverReport, void(const RtcpReportBlock& receiver_report));
  MOCK_METHOD0(OnReceiverIndicatesPictureLoss, void());
  MOCK_METHOD2(OnReceiverCheckpoint,
               void(FrameId frame_id, milliseconds playout_delay));
  MOCK_METHOD1(OnReceiverHasFrames, void(std::vector<FrameId> acks));
  MOCK_METHOD1(OnReceiverIsMissingPackets, void(std::vector<PacketNack> nacks));

 private:
  TaskRunner* const task_runner_;
  UdpSocket::Client* const receiver_;
  const IPEndpoint sender_endpoint_;
  RtcpSession rtcp_session_;
  SenderReportBuilder sender_report_builder_;
  CompoundRtcpParser rtcp_parser_;
  FrameCrypto crypto_;
  RtpPacketizer rtp_packetizer_;

  FrameId max_feedback_frame_id_ = FrameId::first() + kMaxUnackedFrames;

  EncryptedFrame frame_being_sent_;
};

class MockConsumer : public Receiver::Consumer {
 public:
  MOCK_METHOD1(OnFramesReady, void(int next_frame_buffer_size));
};

class ReceiverTest : public testing::Test {
 public:
  ReceiverTest()
      : clock_(Clock::now()),
        task_runner_(&clock_),
        env_(&FakeClock::now, &task_runner_),
        packet_router_(&env_),
        receiver_(&env_,
                  &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}),
        sender_(&task_runner_, &env_) {
    env_.set_socket_error_handler(
        [](Error error) { ASSERT_TRUE(error.ok()) << error; });
    ON_CALL(env_, SendPacket(_))
        .WillByDefault(Invoke([this](absl::Span<const uint8_t> packet) {
          task_runner_.PostTaskWithDelay(
              [sender = &sender_, copy_of_packet = std::vector<uint8_t>(
                                      packet.begin(), packet.end())]() mutable {
                sender->OnPacketFromReceiver(std::move(copy_of_packet));
              },
              kOneWayNetworkDelay);
        }));
    receiver_.SetConsumer(&consumer_);
  }

  ~ReceiverTest() override = default;

  Receiver* receiver() { return &receiver_; }
  MockSender* sender() { return &sender_; }
  MockConsumer* consumer() { return &consumer_; }

  void AdvanceClockAndRunTasks(Clock::duration delta) { clock_.Advance(delta); }
  void RunTasksUntilIdle() { task_runner_.RunTasksUntilIdle(); }

  // Sends the initial Sender Report with lip-sync timing information to
  // "unblock" the Receiver, and confirms the Receiver immediately replies with
  // a corresponding Receiver Report.
  void ExchangeInitialReportPackets() {
    const Clock::time_point start_time = FakeClock::now();
    sender_.SendSenderReport(start_time, SimulatedFrame::GetRtpStartTime());
    AdvanceClockAndRunTasks(
        kOneWayNetworkDelay);  // Transmit report to Receiver.
    // The Receiver will immediately reply with a Receiver Report.
    EXPECT_CALL(sender_,
                OnReceiverCheckpoint(FrameId::leader(), kTargetPlayoutDelay))
        .Times(1);
    AdvanceClockAndRunTasks(kOneWayNetworkDelay);  // Transmit reply to Sender.
    testing::Mock::VerifyAndClearExpectations(&sender_);
  }

  // Consume one frame from the Receiver, and verify that it is the same as the
  // |sent_frame|. Exception: The |reference_time| is the playout time on the
  // Receiver's end, while it refers to the capture time on the Sender's end.
  void ConsumeAndVerifyFrame(const SimulatedFrame& sent_frame) {
    SCOPED_TRACE(testing::Message() << "for frame " << sent_frame.frame_id);

    const int payload_size = receiver()->AdvanceToNextFrame();
    ASSERT_NE(Receiver::kNoFramesReady, payload_size);
    std::vector<uint8_t> buffer(payload_size);
    EncodedFrame received_frame =
        receiver()->ConsumeNextFrame(absl::Span<uint8_t>(buffer));

    EXPECT_EQ(sent_frame.dependency, received_frame.dependency);
    EXPECT_EQ(sent_frame.frame_id, received_frame.frame_id);
    EXPECT_EQ(sent_frame.referenced_frame_id,
              received_frame.referenced_frame_id);
    EXPECT_EQ(sent_frame.rtp_timestamp, received_frame.rtp_timestamp);
    EXPECT_EQ(sent_frame.reference_time + kOneWayNetworkDelay +
                  SimulatedFrame::GetExpectedPlayoutDelay(sent_frame.frame_id -
                                                          FrameId::first()),
              received_frame.reference_time);
    EXPECT_EQ(sent_frame.new_playout_delay, received_frame.new_playout_delay);
    EXPECT_EQ(sent_frame.data, received_frame.data);
  }

  // Consume zero or more frames from the Receiver, verifying that they are the
  // same as the SimulatedFrame that was sent.
  void ConsumeAndVerifyFrames(int first,
                              int last,
                              Clock::time_point start_time) {
    for (int i = first; i <= last; ++i) {
      ConsumeAndVerifyFrame(SimulatedFrame(start_time, i));
    }
  }

 private:
  FakeClock clock_;
  FakeTaskRunner task_runner_;
  testing::NiceMock<MockEnvironment> env_;
  ReceiverPacketRouter packet_router_;
  Receiver receiver_;
  testing::NiceMock<MockSender> sender_;
  testing::NiceMock<MockConsumer> consumer_;
};

// Tests that the Receiver processes RTCP packets correctly and sends RTCP
// reports at regular intervals.
TEST_F(ReceiverTest, ReceivesAndSendsRtcpPackets) {
  // Sender-side expectations, after the Receiver has processed the first Sender
  // Report.
  Clock::time_point receiver_reference_time{};
  EXPECT_CALL(*sender(), OnReceiverReferenceTimeAdvanced(_))
      .WillOnce(SaveArg<0>(&receiver_reference_time));
  RtcpReportBlock receiver_report;
  EXPECT_CALL(*sender(), OnReceiverReport(_))
      .WillOnce(SaveArg<0>(&receiver_report));
  EXPECT_CALL(*sender(),
              OnReceiverCheckpoint(FrameId::leader(), kTargetPlayoutDelay))
      .Times(1);

  // Have the MockSender send a Sender Report with lip-sync timing information.
  const Clock::time_point sender_reference_time = FakeClock::now();
  const RtpTimeTicks sender_rtp_timestamp =
      RtpTimeTicks::FromTimeSinceOrigin(seconds(1), kRtpTimebase);
  const StatusReportId sender_report_id =
      sender()->SendSenderReport(sender_reference_time, sender_rtp_timestamp);

  AdvanceClockAndRunTasks(kRoundTripNetworkDelay);

  // Expect the MockSender got back a Receiver Report that includes its SSRC and
  // the last Sender Report ID.
  testing::Mock::VerifyAndClearExpectations(sender());
  EXPECT_EQ(kSenderSsrc, receiver_report.ssrc);
  EXPECT_EQ(sender_report_id, receiver_report.last_status_report_id);

  // Confirm the clock offset math: Since the Receiver and MockSender share the
  // same underlying FakeClock, the Receiver should be ahead of the Sender,
  // which reflects the simulated one-way network packet travel time (of the
  // Sender Report).
  //
  // Note: The offset can be affected by the lossy conversion when going to and
  // from the wire-format NtpTimestamps. See the unit tests in
  // ntp_time_unittest.cc for further discussion.
  constexpr auto kAllowedNtpRoundingError = microseconds(2);
  EXPECT_NEAR(
      to_microseconds(kOneWayNetworkDelay).count(),
      to_microseconds(receiver_reference_time - sender_reference_time).count(),
      kAllowedNtpRoundingError.count());

  // Without the Sender doing anything, the Receiver should continue providing
  // RTCP reports at regular intervals. Simulate three intervals of time,
  // verifying that the Receiver did send reports.
  Clock::time_point last_receiver_reference_time = receiver_reference_time;
  for (int i = 0; i < 3; ++i) {
    receiver_reference_time = Clock::time_point();
    EXPECT_CALL(*sender(), OnReceiverReferenceTimeAdvanced(_))
        .WillRepeatedly(SaveArg<0>(&receiver_reference_time));
    AdvanceClockAndRunTasks(kRtcpReportInterval);
    testing::Mock::VerifyAndClearExpectations(sender());
    EXPECT_LT(last_receiver_reference_time, receiver_reference_time);
    last_receiver_reference_time = receiver_reference_time;
  }
}

// Tests that the Receiver processes RTP packets, which might arrive in-order or
// out of order, but such that each frame is completely received in-order. Also,
// confirms that target playout delay changes are processed/applied correctly.
TEST_F(ReceiverTest, ReceivesFramesInOrder) {
  const Clock::time_point start_time = FakeClock::now();
  ExchangeInitialReportPackets();

  EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(10);
  for (int i = 0; i <= 9; ++i) {
    EXPECT_CALL(*sender(), OnReceiverCheckpoint(
                               FrameId::first() + i,
                               SimulatedFrame::GetExpectedPlayoutDelay(i)))
        .Times(1);
    EXPECT_CALL(*sender(), OnReceiverIsMissingPackets(_)).Times(0);

    sender()->SetFrameBeingSent(SimulatedFrame(start_time, i));
    // Send the frame's packets in-order half the time, out-of-order the other
    // half.
    const int permutation = (i % 2) ? i : 0;
    sender()->SendRtpPackets(sender()->GetAllPacketIds(permutation));

    AdvanceClockAndRunTasks(kRoundTripNetworkDelay);

    // The Receiver should immediately ACK once it has received all the RTP
    // packets to complete the frame.
    testing::Mock::VerifyAndClearExpectations(sender());

    // Advance to next frame transmission time.
    AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration -
                            kRoundTripNetworkDelay);
  }

  // When the Receiver has all of the frames and they are complete, it should
  // send out a low-frequency periodic RTCP "ping." Verify that there is one and
  // only one "ping" sent when the clock moves forward by one default report
  // interval during a period of inactivity.
  EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::first() + 9,
                                              kTargetPlayoutDelayChange))
      .Times(1);
  AdvanceClockAndRunTasks(kRtcpReportInterval);
  testing::Mock::VerifyAndClearExpectations(sender());

  ConsumeAndVerifyFrames(0, 9, start_time);
  EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());
}

// Tests that the Receiver processes RTP packets, can receive frames out of
// order, and issues the appropriate ACK/NACK feedback to the Sender as it
// realizes what it has and what it's missing.
TEST_F(ReceiverTest, ReceivesFramesOutOfOrder) {
  const Clock::time_point start_time = FakeClock::now();
  ExchangeInitialReportPackets();

  constexpr static int kOutOfOrderFrames[] = {3, 4, 2, 0, 1};
  for (int i : kOutOfOrderFrames) {
    // Expectations are different as each frame is sent and received.
    switch (i) {
      case 3: {
        // Note that frame 4 will not yet be known to the Receiver, and so it
        // should not be mentioned in any of the feedback for this case.
        EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::leader(),
                                                    kTargetPlayoutDelay))
            .Times(AtLeast(1));
        EXPECT_CALL(
            *sender(),
            OnReceiverHasFrames(std::vector<FrameId>({FrameId::first() + 3})))
            .Times(AtLeast(1));
        EXPECT_CALL(*sender(),
                    OnReceiverIsMissingPackets(std::vector<PacketNack>({
                        PacketNack{FrameId::first(), kAllPacketsLost},
                        PacketNack{FrameId::first() + 1, kAllPacketsLost},
                        PacketNack{FrameId::first() + 2, kAllPacketsLost},
                    })))
            .Times(AtLeast(1));
        EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
        break;
      }

      case 4: {
        EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::leader(),
                                                    kTargetPlayoutDelay))
            .Times(AtLeast(1));
        EXPECT_CALL(*sender(),
                    OnReceiverHasFrames(std::vector<FrameId>(
                        {FrameId::first() + 3, FrameId::first() + 4})))
            .Times(AtLeast(1));
        EXPECT_CALL(*sender(),
                    OnReceiverIsMissingPackets(std::vector<PacketNack>({
                        PacketNack{FrameId::first(), kAllPacketsLost},
                        PacketNack{FrameId::first() + 1, kAllPacketsLost},
                        PacketNack{FrameId::first() + 2, kAllPacketsLost},
                    })))
            .Times(AtLeast(1));
        EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
        break;
      }

      case 2: {
        EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::leader(),
                                                    kTargetPlayoutDelay))
            .Times(AtLeast(1));
        EXPECT_CALL(*sender(), OnReceiverHasFrames(std::vector<FrameId>(
                                   {FrameId::first() + 2, FrameId::first() + 3,
                                    FrameId::first() + 4})))
            .Times(AtLeast(1));
        EXPECT_CALL(*sender(),
                    OnReceiverIsMissingPackets(std::vector<PacketNack>({
                        PacketNack{FrameId::first(), kAllPacketsLost},
                        PacketNack{FrameId::first() + 1, kAllPacketsLost},
                    })))
            .Times(AtLeast(1));
        EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
        break;
      }

      case 0: {
        EXPECT_CALL(*sender(),
                    OnReceiverCheckpoint(FrameId::first(), kTargetPlayoutDelay))
            .Times(AtLeast(1));
        EXPECT_CALL(*sender(), OnReceiverHasFrames(std::vector<FrameId>(
                                   {FrameId::first() + 2, FrameId::first() + 3,
                                    FrameId::first() + 4})))
            .Times(AtLeast(1));
        EXPECT_CALL(*sender(),
                    OnReceiverIsMissingPackets(std::vector<PacketNack>(
                        {PacketNack{FrameId::first() + 1, kAllPacketsLost}})))
            .Times(AtLeast(1));
        EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
        break;
      }

      case 1: {
        EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::first() + 4,
                                                    kTargetPlayoutDelay))
            .Times(AtLeast(1));
        EXPECT_CALL(*sender(), OnReceiverHasFrames(_)).Times(0);
        EXPECT_CALL(*sender(), OnReceiverIsMissingPackets(_)).Times(0);
        EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
        break;
      }

      default:
        OSP_NOTREACHED();
    }

    sender()->SetFrameBeingSent(SimulatedFrame(start_time, i));
    sender()->SendRtpPackets(sender()->GetAllPacketIds(i));

    AdvanceClockAndRunTasks(kRoundTripNetworkDelay);

    // While there are known incomplete frames, the Receiver should send RTCP
    // packets more frequently than the default "ping" interval. Thus, advancing
    // the clock by this much should result in several feedback reports
    // transmitted to the Sender.
    AdvanceClockAndRunTasks(kRtcpReportInterval - kRoundTripNetworkDelay);

    testing::Mock::VerifyAndClearExpectations(sender());
    testing::Mock::VerifyAndClearExpectations(consumer());
  }

  ConsumeAndVerifyFrames(0, 4, start_time);
  EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());
}

// Tests that the Receiver will respond to a key frame request from its client
// by sending a Picture Loss Indicator (PLI) to the Sender, and then will
// automatically stop sending the PLI once a key frame has been received.
TEST_F(ReceiverTest, RequestsKeyFrameToRectifyPictureLoss) {
  const Clock::time_point start_time = FakeClock::now();
  ExchangeInitialReportPackets();

  // Send and Receive three frames in-order, normally.
  for (int i = 0; i <= 2; ++i) {
    EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
    EXPECT_CALL(*sender(),
                OnReceiverCheckpoint(FrameId::first() + i, kTargetPlayoutDelay))
        .Times(1);
    sender()->SetFrameBeingSent(SimulatedFrame(start_time, i));
    sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
    AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
    testing::Mock::VerifyAndClearExpectations(sender());
    testing::Mock::VerifyAndClearExpectations(consumer());
    // Advance to next frame transmission time.
    AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration -
                            kRoundTripNetworkDelay);
  }
  ConsumeAndVerifyFrames(0, 2, start_time);

  // Simulate the Consumer requesting a key frame after picture loss (e.g., a
  // decoder failure). Ensure the Sender is immediately notified.
  EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(1);
  receiver()->RequestKeyFrame();
  AdvanceClockAndRunTasks(kOneWayNetworkDelay);  // Propagate request to Sender.
  testing::Mock::VerifyAndClearExpectations(sender());

  // The Sender sends another frame that is not a key frame and, upon receipt,
  // the Receiver should repeat its "cry" for a key frame.
  EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
  EXPECT_CALL(*sender(),
              OnReceiverCheckpoint(FrameId::first() + 3, kTargetPlayoutDelay))
      .Times(1);
  EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(AtLeast(1));
  sender()->SetFrameBeingSent(SimulatedFrame(start_time, 3));
  sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
  AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration - kOneWayNetworkDelay);
  testing::Mock::VerifyAndClearExpectations(sender());
  testing::Mock::VerifyAndClearExpectations(consumer());
  ConsumeAndVerifyFrames(3, 3, start_time);

  // Finally, the Sender responds to the PLI condition by sending a key frame.
  // Confirm the Receiver has stopped indicating picture loss after having
  // received the key frame.
  EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
  EXPECT_CALL(*sender(),
              OnReceiverCheckpoint(FrameId::first() + 4, kTargetPlayoutDelay))
      .Times(1);
  EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(0);
  SimulatedFrame key_frame(start_time, 4);
  key_frame.dependency = EncodedFrame::KEY_FRAME;
  key_frame.referenced_frame_id = key_frame.frame_id;
  sender()->SetFrameBeingSent(key_frame);
  sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
  AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
  testing::Mock::VerifyAndClearExpectations(sender());
  testing::Mock::VerifyAndClearExpectations(consumer());

  // The client has not yet consumed the key frame, so any calls to
  // RequestKeyFrame() should not set the PLI condition again.
  EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(0);
  receiver()->RequestKeyFrame();
  AdvanceClockAndRunTasks(kOneWayNetworkDelay);
  testing::Mock::VerifyAndClearExpectations(sender());

  // After consuming the requested key frame, the client should be able to set
  // the PLI condition again with another RequestKeyFrame() call.
  ConsumeAndVerifyFrame(key_frame);
  EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(1);
  receiver()->RequestKeyFrame();
  AdvanceClockAndRunTasks(kOneWayNetworkDelay);
  testing::Mock::VerifyAndClearExpectations(sender());
}

// Tests that the Receiver will start dropping packets once its frame queue is
// full (i.e., when the consumer is not pulling them out of the queue). Since
// the Receiver will stop ACK'ing frames, the Sender will become stalled.
TEST_F(ReceiverTest, EatsItsFill) {
  const Clock::time_point start_time = FakeClock::now();
  ExchangeInitialReportPackets();

  // Send and Receive the maximum possible number of frames in-order, normally.
  for (int i = 0; i < kMaxUnackedFrames; ++i) {
    EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
    EXPECT_CALL(*sender(), OnReceiverCheckpoint(
                               FrameId::first() + i,
                               SimulatedFrame::GetExpectedPlayoutDelay(i)))
        .Times(1);
    sender()->SetFrameBeingSent(SimulatedFrame(start_time, i));
    sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
    AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
    testing::Mock::VerifyAndClearExpectations(sender());
    testing::Mock::VerifyAndClearExpectations(consumer());
  }

  // Sending one more frame should be ignored. Over and over. None of the
  // feedback reports from the Receiver should indicate it is collecting packets
  // for future frames.
  int ignored_frame = kMaxUnackedFrames;
  for (int i = 0; i < 5; ++i) {
    EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
    EXPECT_CALL(*sender(),
                OnReceiverCheckpoint(FrameId::first() + (ignored_frame - 1),
                                     kTargetPlayoutDelayChange))
        .Times(AtLeast(0));
    EXPECT_CALL(*sender(), OnReceiverIsMissingPackets(_)).Times(0);
    sender()->SetFrameBeingSent(SimulatedFrame(start_time, ignored_frame));
    sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
    AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
    testing::Mock::VerifyAndClearExpectations(sender());
    testing::Mock::VerifyAndClearExpectations(consumer());
  }

  // Consume only one frame, and confirm the Receiver allows only one frame more
  // to be received.
  ConsumeAndVerifyFrames(0, 0, start_time);
  int no_longer_ignored_frame = ignored_frame;
  ++ignored_frame;
  EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(AtLeast(1));
  EXPECT_CALL(*sender(),
              OnReceiverCheckpoint(FrameId::first() + no_longer_ignored_frame,
                                   kTargetPlayoutDelayChange))
      .Times(AtLeast(1));
  EXPECT_CALL(*sender(), OnReceiverIsMissingPackets(_)).Times(0);
  // This frame should be received successfully.
  sender()->SetFrameBeingSent(
      SimulatedFrame(start_time, no_longer_ignored_frame));
  sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
  AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
  // This second frame should be ignored, however.
  sender()->SetFrameBeingSent(SimulatedFrame(start_time, ignored_frame));
  sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
  AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
  testing::Mock::VerifyAndClearExpectations(sender());
  testing::Mock::VerifyAndClearExpectations(consumer());
}

// Tests that incomplete frames that would be played-out too late are dropped,
// but only as inter-frame data dependency requirements permit, and only if no
// target playout delay change information would have been missed.
TEST_F(ReceiverTest, DropsLateFrames) {
  const Clock::time_point start_time = FakeClock::now();
  ExchangeInitialReportPackets();

  // Before any packets have been sent/received, the Receiver should indicate no
  // frames are ready.
  EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());

  // Set a ridiculously-large estimated player processing time so that the logic
  // thinks every frame going to play out too late.
  receiver()->SetPlayerProcessingTime(seconds(3));

  // In this test there are eight frames total:
  //   - Frame 0: Key frame.
  //   - Frames 1-4: Non-key frames.
  //   - Frame 5: Non-key frame that contains a target playout delay change.
  //   - Frame 6: Key frame.
  //   - Frame 7: Non-key frame.
  ASSERT_EQ(SimulatedFrame::kPlayoutChangeAtFrame, 5);
  SimulatedFrame frames[8] = {{start_time, 0}, {start_time, 1}, {start_time, 2},
                              {start_time, 3}, {start_time, 4}, {start_time, 5},
                              {start_time, 6}, {start_time, 7}};
  frames[6].dependency = EncodedFrame::KEY_FRAME;
  frames[6].referenced_frame_id = frames[6].frame_id;

  // Send just packet 1 (NOT packet 0) of all the frames. The Receiver should
  // never notify the consumer via the callback, nor report that any frames are
  // ready, because none of the frames have been completely received.
  EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
  EXPECT_CALL(*sender(), OnReceiverCheckpoint(_, _)).Times(0);
  for (int i = 0; i <= 7; ++i) {
    sender()->SetFrameBeingSent(frames[i]);
    // Assumption: There are at least three packets in each frame, else the test
    // is not exercising the logic meaningfully.
    ASSERT_LE(size_t{3}, sender()->GetAllPacketIds(0).size());
    sender()->SendRtpPackets({FramePacketId{1}});
    AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
  }
  testing::Mock::VerifyAndClearExpectations(consumer());
  testing::Mock::VerifyAndClearExpectations(sender());
  EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());

  // Send all the packets of Frame 6 (the second key frame) and Frame 7. The
  // Receiver still cannot drop any frames because it has not seen packet 0 of
  // every prior frame. In other words, it cannot ignore any possibility of a
  // target playout delay change from the Sender.
  EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
  EXPECT_CALL(*sender(), OnReceiverCheckpoint(_, _)).Times(0);
  for (int i = 6; i <= 7; ++i) {
    sender()->SetFrameBeingSent(frames[i]);
    sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
  }
  AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
  testing::Mock::VerifyAndClearExpectations(consumer());
  testing::Mock::VerifyAndClearExpectations(sender());
  EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());

  // Send packet 0 for all but Frame 5, which contains a target playout delay
  // change. All but the last two frames will still be incomplete. The Receiver
  // still cannot drop any frames because it doesn't know whether Frame 5 had a
  // target playout delay change.
  EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
  EXPECT_CALL(*sender(), OnReceiverCheckpoint(_, _)).Times(0);
  for (int i = 0; i <= 7; ++i) {
    if (i == 5) {
      continue;
    }
    sender()->SetFrameBeingSent(frames[i]);
    sender()->SendRtpPackets({FramePacketId{0}});
  }
  AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
  testing::Mock::VerifyAndClearExpectations(consumer());
  testing::Mock::VerifyAndClearExpectations(sender());
  EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());

  // Finally, send packet 0 for Frame 5. Now, the Receiver will drop every frame
  // before the completely-received second key frame, as they are all still
  // incomplete and will play-out too late. When it drops the frames, it will
  // notify the sender of the new checkpoint so that it stops trying to
  // re-transmit the dropped frames.
  EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
  EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::first() + 7,
                                              kTargetPlayoutDelayChange))
      .Times(1);
  sender()->SetFrameBeingSent(frames[5]);
  sender()->SendRtpPackets({FramePacketId{0}});
  AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
  // Note: Consuming Frame 6 will trigger the checkpoint advancement, since the
  // call to AdvanceToNextFrame() contains the frame skipping/dropping logic.
  ConsumeAndVerifyFrame(frames[6]);
  testing::Mock::VerifyAndClearExpectations(consumer());
  testing::Mock::VerifyAndClearExpectations(sender());

  // After consuming Frame 6, the Receiver knows Frame 7 is also available and
  // should have scheduled an immediate task to notify the Consumer of this.
  EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
  AdvanceClockAndRunTasks(kOneWayNetworkDelay);
  testing::Mock::VerifyAndClearExpectations(consumer());

  // Now consume Frame 7. This shouldn't trigger any further checkpoint
  // advancement.
  EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
  EXPECT_CALL(*sender(), OnReceiverCheckpoint(_, _)).Times(0);
  ConsumeAndVerifyFrame(frames[7]);
  AdvanceClockAndRunTasks(kOneWayNetworkDelay);
  testing::Mock::VerifyAndClearExpectations(consumer());
  testing::Mock::VerifyAndClearExpectations(sender());
}

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