// Copyright 2014 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 <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <memory>

#include "base/big_endian.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/base/fake_single_thread_task_runner.h"
#include "media/cast/net/pacing/paced_sender.h"
#include "testing/gmock/include/gmock/gmock.h"

using testing::_;

namespace media {
namespace cast {
namespace {

const uint8_t kValue = 123;
const size_t kSize1 = 101;
const size_t kSize2 = 102;
const size_t kSize3 = 103;
const size_t kSize4 = 104;
const size_t kNackSize = 105;
const int64_t kStartMillisecond = INT64_C(12345678900000);
const uint32_t kVideoSsrc = 0x1234;
const uint32_t kAudioSsrc = 0x5678;
const uint32_t kVideoFrameRtpTimestamp = 12345;
const uint32_t kAudioFrameRtpTimestamp = 23456;

// RTCP packets don't really have a packet ID.  However, the bytes where
// TestPacketSender checks for the ID should be set to 31611, so we'll just
// check that.
const uint16_t kRtcpPacketIdMagic = UINT16_C(31611);

class TestPacketSender : public PacketTransport {
 public:
  TestPacketSender() : bytes_sent_(0) {}

  bool SendPacket(PacketRef packet, base::OnceClosure cb) final {
    EXPECT_FALSE(expected_packet_sizes_.empty());
    size_t expected_packet_size = expected_packet_sizes_.front();
    expected_packet_sizes_.pop_front();
    EXPECT_EQ(expected_packet_size, packet->data.size());
    bytes_sent_ += packet->data.size();

    // Parse for the packet ID and confirm it is the next one we expect.
    EXPECT_LE(kSize1, packet->data.size());
    base::BigEndianReader reader(reinterpret_cast<char*>(&packet->data[0]),
                                 packet->data.size());
    bool success = reader.Skip(14);
    uint16_t packet_id = 0xffff;
    success &= reader.ReadU16(&packet_id);
    EXPECT_TRUE(success);
    const uint16_t expected_packet_id = expected_packet_ids_.front();
    expected_packet_ids_.pop_front();
    EXPECT_EQ(expected_packet_id, packet_id);

    return true;
  }

  int64_t GetBytesSent() final { return bytes_sent_; }

  void StartReceiving(PacketReceiverCallbackWithStatus packet_receiver) final {}

  void StopReceiving() final {}

  void AddExpectedSizesAndPacketIds(int packet_size,
                                    uint16_t first_packet_id,
                                    int sequence_length) {
    for (int i = 0; i < sequence_length; ++i) {
      expected_packet_sizes_.push_back(packet_size);
      expected_packet_ids_.push_back(first_packet_id++);
    }
  }

  bool expecting_nothing_else() const { return expected_packet_sizes_.empty(); }

 private:
  base::circular_deque<int> expected_packet_sizes_;
  base::circular_deque<uint16_t> expected_packet_ids_;
  int64_t bytes_sent_;

  DISALLOW_COPY_AND_ASSIGN(TestPacketSender);
};

class PacedSenderTest : public ::testing::Test {
 protected:
  PacedSenderTest() {
    testing_clock_.Advance(base::Milliseconds(kStartMillisecond));
    task_runner_ = new FakeSingleThreadTaskRunner(&testing_clock_);
    paced_sender_ = std::make_unique<PacedSender>(
        kTargetBurstSize, kMaxBurstSize, &testing_clock_, &packet_events_,
        &mock_transport_, task_runner_);
    paced_sender_->RegisterSsrc(kAudioSsrc, true);
    paced_sender_->RegisterSsrc(kVideoSsrc, false);
  }

  static void UpdateCastTransportStatus(CastTransportStatus status) {
    NOTREACHED();
  }

  SendPacketVector CreateSendPacketVector(size_t packet_size,
                                          int num_of_packets_in_frame,
                                          bool audio) {
    DCHECK_GE(packet_size, 12u);
    SendPacketVector packets;
    base::TimeTicks frame_tick = testing_clock_.NowTicks();
    // Advance the clock so that we don't get the same |frame_tick|
    // next time this function is called.
    testing_clock_.Advance(base::Milliseconds(1));
    for (int i = 0; i < num_of_packets_in_frame; ++i) {
      PacketKey key(frame_tick, audio ? kAudioSsrc : kVideoSsrc,
                    FrameId::first(), i);

      PacketRef packet(new base::RefCountedData<Packet>);
      packet->data.resize(packet_size, kValue);
      // Fill-in packet header fields to test the header parsing (for populating
      // the logging events).
      base::BigEndianWriter writer(reinterpret_cast<char*>(&packet->data[0]),
                                   packet_size);
      bool success = writer.Skip(4);
      success &= writer.WriteU32(audio ? kAudioFrameRtpTimestamp
                                       : kVideoFrameRtpTimestamp);
      success &= writer.WriteU32(audio ? kAudioSsrc : kVideoSsrc);
      success &= writer.Skip(2);
      success &= writer.WriteU16(i);
      success &= writer.WriteU16(num_of_packets_in_frame - 1);
      CHECK(success);
      packets.push_back(std::make_pair(key, packet));
    }
    return packets;
  }

  void SendWithoutBursting(const SendPacketVector& packets) {
    const size_t kBatchSize = 10;
    for (size_t i = 0; i < packets.size(); i += kBatchSize) {
      const SendPacketVector next_batch(
          packets.begin() + i,
          packets.begin() + i + std::min(packets.size() - i, kBatchSize));
      ASSERT_TRUE(paced_sender_->SendPackets(next_batch));
      testing_clock_.Advance(base::Milliseconds(10));
      task_runner_->RunTasks();
    }
  }

  // Use this function to drain the packet list in PacedSender without having
  // to test the pacing implementation details.
  bool RunUntilEmpty(int max_tries) {
    for (int i = 0; i < max_tries; i++) {
      testing_clock_.Advance(base::Milliseconds(10));
      task_runner_->RunTasks();
      if (mock_transport_.expecting_nothing_else())
        return true;
    }

    return mock_transport_.expecting_nothing_else();
  }

  std::vector<PacketEvent> packet_events_;
  base::SimpleTestTickClock testing_clock_;
  TestPacketSender mock_transport_;
  scoped_refptr<FakeSingleThreadTaskRunner> task_runner_;
  std::unique_ptr<PacedSender> paced_sender_;

  DISALLOW_COPY_AND_ASSIGN(PacedSenderTest);
};

}  // namespace

TEST_F(PacedSenderTest, PassThroughRtcp) {
  SendPacketVector packets = CreateSendPacketVector(kSize1, 1, true);

  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  EXPECT_TRUE(paced_sender_->SendPackets(packets));
  EXPECT_TRUE(paced_sender_->ResendPackets(packets, DedupInfo()));

  mock_transport_.AddExpectedSizesAndPacketIds(kSize2, kRtcpPacketIdMagic, 1);
  Packet tmp(kSize2, kValue);
  EXPECT_TRUE(
      paced_sender_->SendRtcpPacket(1, new base::RefCountedData<Packet>(tmp)));
}

TEST_F(PacedSenderTest, BasicPace) {
  int num_of_packets = 27;
  SendPacketVector packets =
      CreateSendPacketVector(kSize1, num_of_packets, false);
  const base::TimeTicks earliest_event_timestamp = testing_clock_.NowTicks();

  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 10);
  EXPECT_TRUE(paced_sender_->SendPackets(packets));

  // Check that we get the next burst.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(10), 10);

  base::TimeDelta timeout = base::Milliseconds(10);
  testing_clock_.Advance(timeout);
  task_runner_->RunTasks();

  // If we call process too early make sure we don't send any packets.
  timeout = base::Milliseconds(5);
  testing_clock_.Advance(timeout);
  task_runner_->RunTasks();

  // Check that we get the next burst.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(20), 7);
  testing_clock_.Advance(timeout);
  task_runner_->RunTasks();

  // Check that we don't get any more packets.
  EXPECT_TRUE(RunUntilEmpty(3));
  const base::TimeTicks latest_event_timestamp = testing_clock_.NowTicks();

  // Check that packet logging events match expected values.
  EXPECT_EQ(num_of_packets, static_cast<int>(packet_events_.size()));
  uint16_t expected_packet_id = 0;
  for (const PacketEvent& e : packet_events_) {
    ASSERT_LE(earliest_event_timestamp, e.timestamp);
    ASSERT_GE(latest_event_timestamp, e.timestamp);
    ASSERT_EQ(PACKET_SENT_TO_NETWORK, e.type);
    ASSERT_EQ(VIDEO_EVENT, e.media_type);
    ASSERT_EQ(kVideoFrameRtpTimestamp, e.rtp_timestamp.lower_32_bits());
    ASSERT_EQ(num_of_packets - 1, e.max_packet_id);
    ASSERT_EQ(expected_packet_id++, e.packet_id);
    ASSERT_EQ(kSize1, e.size);
  }
}

TEST_F(PacedSenderTest, PaceWithNack) {
  // Testing what happen when we get multiple NACK requests for a fully lost
  // frames just as we sent the first packets in a frame.
  int num_of_packets_in_frame = 12;
  int num_of_packets_in_nack = 12;

  SendPacketVector nack_packets =
      CreateSendPacketVector(kNackSize, num_of_packets_in_nack, false);

  SendPacketVector first_frame_packets =
      CreateSendPacketVector(kSize1, num_of_packets_in_frame, false);

  SendPacketVector second_frame_packets =
      CreateSendPacketVector(kSize2, num_of_packets_in_frame, true);

  // Check that the first burst of the frame go out on the wire.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 10);
  EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets));

  // Add first NACK request.
  EXPECT_TRUE(paced_sender_->ResendPackets(nack_packets, DedupInfo()));

  // Check that we get the first NACK burst.
  mock_transport_.AddExpectedSizesAndPacketIds(kNackSize, UINT16_C(0), 10);
  base::TimeDelta timeout = base::Milliseconds(10);
  testing_clock_.Advance(timeout);
  task_runner_->RunTasks();

  // Add second NACK request.
  EXPECT_TRUE(paced_sender_->ResendPackets(nack_packets, DedupInfo()));

  // Check that we get the next NACK burst.
  mock_transport_.AddExpectedSizesAndPacketIds(kNackSize, UINT16_C(10), 2);
  mock_transport_.AddExpectedSizesAndPacketIds(kNackSize, UINT16_C(0), 8);
  testing_clock_.Advance(timeout);
  task_runner_->RunTasks();

  // End of NACK plus two packets from the oldest frame.
  // Note that two of the NACKs have been de-duped.
  mock_transport_.AddExpectedSizesAndPacketIds(kNackSize, UINT16_C(8), 2);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(10), 2);
  testing_clock_.Advance(timeout);
  task_runner_->RunTasks();

  // Add second frame.
  // Make sure we don't delay the second frame due to the previous packets.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize2, UINT16_C(0), 10);
  EXPECT_TRUE(paced_sender_->SendPackets(second_frame_packets));

  // Last packets of frame 2.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize2, UINT16_C(10), 2);
  testing_clock_.Advance(timeout);
  task_runner_->RunTasks();

  // No more packets.
  EXPECT_TRUE(RunUntilEmpty(5));

  int expected_video_network_event_count = num_of_packets_in_frame;
  int expected_video_retransmitted_event_count = 2 * num_of_packets_in_nack;
  expected_video_retransmitted_event_count -= 2;  // 2 packets deduped
  int expected_audio_network_event_count = num_of_packets_in_frame;
  EXPECT_EQ(expected_video_network_event_count +
                expected_video_retransmitted_event_count +
                expected_audio_network_event_count,
            static_cast<int>(packet_events_.size()));
  int audio_network_event_count = 0;
  int video_network_event_count = 0;
  int video_retransmitted_event_count = 0;
  for (const PacketEvent& e : packet_events_) {
    if (e.type == PACKET_SENT_TO_NETWORK) {
      if (e.media_type == VIDEO_EVENT)
        video_network_event_count++;
      else
        audio_network_event_count++;
    } else if (e.type == PACKET_RETRANSMITTED) {
      if (e.media_type == VIDEO_EVENT)
        video_retransmitted_event_count++;
    } else {
      FAIL() << "Got unexpected event type " << CastLoggingToString(e.type);
    }
  }
  EXPECT_EQ(expected_audio_network_event_count, audio_network_event_count);
  EXPECT_EQ(expected_video_network_event_count, video_network_event_count);
  EXPECT_EQ(expected_video_retransmitted_event_count,
            video_retransmitted_event_count);
}

TEST_F(PacedSenderTest, PaceWith60fps) {
  // Testing what happen when we get multiple NACK requests for a fully lost
  // frames just as we sent the first packets in a frame.
  int num_of_packets_in_frame = 17;

  SendPacketVector first_frame_packets =
      CreateSendPacketVector(kSize1, num_of_packets_in_frame, false);

  SendPacketVector second_frame_packets =
      CreateSendPacketVector(kSize2, num_of_packets_in_frame, false);

  SendPacketVector third_frame_packets =
      CreateSendPacketVector(kSize3, num_of_packets_in_frame, false);

  SendPacketVector fourth_frame_packets =
      CreateSendPacketVector(kSize4, num_of_packets_in_frame, false);

  base::TimeDelta timeout_10ms = base::Milliseconds(10);

  // Check that the first burst of the frame go out on the wire.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 10);
  EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets));

  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(10), 7);
  testing_clock_.Advance(timeout_10ms);
  task_runner_->RunTasks();

  testing_clock_.Advance(base::Milliseconds(6));

  // Add second frame, after 16 ms.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize2, UINT16_C(0), 3);
  EXPECT_TRUE(paced_sender_->SendPackets(second_frame_packets));
  testing_clock_.Advance(base::Milliseconds(4));

  mock_transport_.AddExpectedSizesAndPacketIds(kSize2, UINT16_C(3), 10);
  testing_clock_.Advance(timeout_10ms);
  task_runner_->RunTasks();

  mock_transport_.AddExpectedSizesAndPacketIds(kSize2, UINT16_C(13), 4);
  testing_clock_.Advance(timeout_10ms);
  task_runner_->RunTasks();

  testing_clock_.Advance(base::Milliseconds(3));

  // Add third frame, after 33 ms.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize3, UINT16_C(0), 6);
  EXPECT_TRUE(paced_sender_->SendPackets(third_frame_packets));

  mock_transport_.AddExpectedSizesAndPacketIds(kSize3, UINT16_C(6), 10);
  testing_clock_.Advance(base::Milliseconds(7));
  task_runner_->RunTasks();

  // Add fourth frame, after 50 ms.
  EXPECT_TRUE(paced_sender_->SendPackets(fourth_frame_packets));

  mock_transport_.AddExpectedSizesAndPacketIds(kSize3, UINT16_C(16), 1);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize4, UINT16_C(0), 9);
  testing_clock_.Advance(timeout_10ms);
  task_runner_->RunTasks();

  mock_transport_.AddExpectedSizesAndPacketIds(kSize4, UINT16_C(9), 8);
  testing_clock_.Advance(timeout_10ms);
  task_runner_->RunTasks();

  testing_clock_.Advance(timeout_10ms);
  task_runner_->RunTasks();

  testing_clock_.Advance(timeout_10ms);
  task_runner_->RunTasks();

  // No more packets.
  EXPECT_TRUE(RunUntilEmpty(5));
}

TEST_F(PacedSenderTest, SendPriority) {
  // Actual order to the network is:
  // 1. Video packets x 10.
  // 2. RTCP packet x 1.
  // 3. Audio packet x 1.
  // 4. Video retransmission packet x 10.
  // 5. Video packet x 10.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize2, UINT16_C(0), 10);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize3, kRtcpPacketIdMagic, 1);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize4, UINT16_C(0), 10);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize2, UINT16_C(10), 10);

  paced_sender_->RegisterPrioritySsrc(kAudioSsrc);

  // Retransmission packets with the earlier timestamp.
  SendPacketVector resend_packets = CreateSendPacketVector(kSize4, 10, false);
  testing_clock_.Advance(base::Milliseconds(10));

  // Send 20 normal video packets. Only 10 will be sent in this
  // call, the rest will be sitting in the queue waiting for pacing.
  EXPECT_TRUE(
      paced_sender_->SendPackets(CreateSendPacketVector(kSize2, 20, false)));

  testing_clock_.Advance(base::Milliseconds(10));

  // Send normal audio packet. This is queued and will be sent
  // earlier than video packets.
  EXPECT_TRUE(
      paced_sender_->SendPackets(CreateSendPacketVector(kSize1, 1, true)));

  // Send RTCP packet. This is queued and will be sent first.
  EXPECT_TRUE(paced_sender_->SendRtcpPacket(
      kVideoSsrc, new base::RefCountedData<Packet>(Packet(kSize3, kValue))));

  // Resend video packets. This is queued and will be sent
  // earlier than normal video packets.
  EXPECT_TRUE(paced_sender_->ResendPackets(resend_packets, DedupInfo()));

  // Roll the clock. Queued packets will be sent in this order:
  // 1. RTCP packet x 1.
  // 2. Audio packet x 1.
  // 3. Video retransmission packet x 10.
  // 4. Video packet x 10.
  task_runner_->RunTasks();
  EXPECT_TRUE(RunUntilEmpty(4));
}

TEST_F(PacedSenderTest, GetLastByteSent) {
  SendPacketVector packets1 = CreateSendPacketVector(kSize1, 1, true);
  SendPacketVector packets2 = CreateSendPacketVector(kSize1, 1, false);

  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  EXPECT_TRUE(paced_sender_->SendPackets(packets1));
  EXPECT_EQ(static_cast<int64_t>(kSize1),
            paced_sender_->GetLastByteSentForPacket(packets1[0].first));
  EXPECT_EQ(static_cast<int64_t>(kSize1),
            paced_sender_->GetLastByteSentForSsrc(kAudioSsrc));
  EXPECT_EQ(0, paced_sender_->GetLastByteSentForSsrc(kVideoSsrc));

  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  EXPECT_TRUE(paced_sender_->SendPackets(packets2));
  EXPECT_EQ(static_cast<int64_t>(2 * kSize1),
            paced_sender_->GetLastByteSentForPacket(packets2[0].first));
  EXPECT_EQ(static_cast<int64_t>(kSize1),
            paced_sender_->GetLastByteSentForSsrc(kAudioSsrc));
  EXPECT_EQ(static_cast<int64_t>(2 * kSize1),
            paced_sender_->GetLastByteSentForSsrc(kVideoSsrc));

  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  EXPECT_TRUE(paced_sender_->ResendPackets(packets1, DedupInfo()));
  EXPECT_EQ(static_cast<int64_t>(3 * kSize1),
            paced_sender_->GetLastByteSentForPacket(packets1[0].first));
  EXPECT_EQ(static_cast<int64_t>(3 * kSize1),
            paced_sender_->GetLastByteSentForSsrc(kAudioSsrc));
  EXPECT_EQ(static_cast<int64_t>(2 * kSize1),
            paced_sender_->GetLastByteSentForSsrc(kVideoSsrc));

  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  EXPECT_TRUE(paced_sender_->ResendPackets(packets2, DedupInfo()));
  EXPECT_EQ(static_cast<int64_t>(4 * kSize1),
            paced_sender_->GetLastByteSentForPacket(packets2[0].first));
  EXPECT_EQ(static_cast<int64_t>(3 * kSize1),
            paced_sender_->GetLastByteSentForSsrc(kAudioSsrc));
  EXPECT_EQ(static_cast<int64_t>(4 * kSize1),
            paced_sender_->GetLastByteSentForSsrc(kVideoSsrc));
}

TEST_F(PacedSenderTest, DedupWithResendInterval) {
  SendPacketVector packets = CreateSendPacketVector(kSize1, 1, true);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  EXPECT_TRUE(paced_sender_->SendPackets(packets));
  testing_clock_.Advance(base::Milliseconds(10));

  DedupInfo dedup_info;
  dedup_info.resend_interval = base::Milliseconds(20);

  // This packet will not be sent.
  EXPECT_TRUE(paced_sender_->ResendPackets(packets, dedup_info));
  EXPECT_EQ(static_cast<int64_t>(kSize1), mock_transport_.GetBytesSent());

  dedup_info.resend_interval = base::Milliseconds(5);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 1);
  EXPECT_TRUE(paced_sender_->ResendPackets(packets, dedup_info));
  EXPECT_EQ(static_cast<int64_t>(2 * kSize1), mock_transport_.GetBytesSent());
}

TEST_F(PacedSenderTest, AllPacketsInSameFrameAreResentFairly) {
  const int kNumPackets = 400;
  SendPacketVector packets = CreateSendPacketVector(kSize1, kNumPackets, false);

  // Send a large frame (400 packets, yeah!).  Confirm that the paced sender
  // sends each packet in the frame exactly once.
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0),
                                               kNumPackets);
  SendWithoutBursting(packets);
  ASSERT_TRUE(mock_transport_.expecting_nothing_else());

  // Resend packets 2 and 3.  Confirm that the paced sender sends them.  Then,
  // resend all of the first 10 packets.  The paced sender should send packets
  // 0, 1, and 4 through 9 first, and then 2 and 3.
  SendPacketVector couple_of_packets;
  couple_of_packets.push_back(packets[2]);
  couple_of_packets.push_back(packets[3]);

  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(2), 2);
  SendWithoutBursting(couple_of_packets);
  ASSERT_TRUE(mock_transport_.expecting_nothing_else());

  SendPacketVector first_ten_packets;
  for (size_t i = 0; i < 10; ++i)
    first_ten_packets.push_back(packets[i]);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(0), 2);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(4), 6);
  mock_transport_.AddExpectedSizesAndPacketIds(kSize1, UINT16_C(2), 2);
  SendWithoutBursting(first_ten_packets);
  ASSERT_TRUE(mock_transport_.expecting_nothing_else());
}

}  // namespace cast
}  // namespace media
