// 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 <vector>

#include "base/bind.h"
#include "base/macros.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/pacing/paced_sender.h"
#include "media/cast/net/rtcp/receiver_rtcp_session.h"
#include "media/cast/net/rtcp/rtcp_builder.h"
#include "media/cast/net/rtcp/rtcp_session.h"
#include "media/cast/net/rtcp/rtcp_utility.h"
#include "media/cast/net/rtcp/sender_rtcp_session.h"
#include "media/cast/test/skewed_tick_clock.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace media {
namespace cast {

namespace {

media::cast::RtcpTimeData CreateRtcpTimeData(base::TimeTicks now) {
  media::cast::RtcpTimeData ret;
  ret.timestamp = now;
  media::cast::ConvertTimeTicksToNtp(now, &ret.ntp_seconds, &ret.ntp_fraction);
  return ret;
}

using testing::_;

static const uint32_t kSenderSsrc = 0x10203;
static const uint32_t kReceiverSsrc = 0x40506;
static const int kInitialReceiverClockOffsetSeconds = -5;
static const uint16_t kTargetDelayMs = 100;

class FakeRtcpTransport : public PacedPacketSender {
 public:
  explicit FakeRtcpTransport(base::SimpleTestTickClock* clock)
      : clock_(clock), packet_delay_(base::Milliseconds(42)) {}

  void set_rtcp_destination(RtcpSession* rtcp_session) {
    rtcp_session_ = rtcp_session;
  }

  base::TimeDelta packet_delay() const { return packet_delay_; }
  void set_packet_delay(base::TimeDelta delay) { packet_delay_ = delay; }

  bool SendRtcpPacket(uint32_t ssrc, PacketRef packet) final {
    clock_->Advance(packet_delay_);
    rtcp_session_->IncomingRtcpPacket(&packet->data[0], packet->data.size());
    return true;
  }

  bool SendPackets(const SendPacketVector& packets) final { return false; }

  bool ResendPackets(const SendPacketVector& packets,
                     const DedupInfo& dedup_info) final {
    return false;
  }

  void CancelSendingPacket(const PacketKey& packet_key) final {}

 private:
  base::SimpleTestTickClock* const clock_;
  base::TimeDelta packet_delay_;
  RtcpSession* rtcp_session_;  //  RTCP destination.

  DISALLOW_COPY_AND_ASSIGN(FakeRtcpTransport);
};

}  // namespace

class RtcpTest : public ::testing::Test, public RtcpObserver {
 protected:
  RtcpTest()
      : sender_clock_(new base::SimpleTestTickClock()),
        receiver_clock_(new test::SkewedTickClock(sender_clock_.get())),
        rtp_sender_pacer_(sender_clock_.get()),
        rtp_receiver_pacer_(sender_clock_.get()),
        rtcp_at_rtp_sender_(sender_clock_.get(),
                            &rtp_sender_pacer_,
                            this,
                            kSenderSsrc,
                            kReceiverSsrc),
        rtcp_at_rtp_receiver_(receiver_clock_.get(),
                              kReceiverSsrc,
                              kSenderSsrc),
        received_pli_(false) {
    sender_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
    receiver_clock_->SetSkew(1.0,  // No skew.
                             base::Seconds(kInitialReceiverClockOffsetSeconds));

    rtp_sender_pacer_.set_rtcp_destination(&rtcp_at_rtp_receiver_);
    rtp_receiver_pacer_.set_rtcp_destination(&rtcp_at_rtp_sender_);
  }

  ~RtcpTest() override = default;

  // RtcpObserver implementation.
  void OnReceivedCastMessage(const RtcpCastMessage& cast_message) override {
    last_cast_message_ = cast_message;
  }
  void OnReceivedRtt(base::TimeDelta round_trip_time) override {
    current_round_trip_time_ = round_trip_time;
  }
  void OnReceivedReceiverLog(const RtcpReceiverLogMessage& logs) override {
    RtcpReceiverLogMessage().swap(last_logs_);

    // Make a copy of the logs.
    for (const RtcpReceiverFrameLogMessage& frame_log_msg : logs) {
      last_logs_.push_back(
          RtcpReceiverFrameLogMessage(frame_log_msg.rtp_timestamp_));
      for (const RtcpReceiverEventLogMessage& event_log_msg :
           frame_log_msg.event_log_messages_) {
        RtcpReceiverEventLogMessage event_log;
        event_log.type = event_log_msg.type;
        event_log.event_timestamp = event_log_msg.event_timestamp;
        event_log.delay_delta = event_log_msg.delay_delta;
        event_log.packet_id = event_log_msg.packet_id;
        last_logs_.back().event_log_messages_.push_back(event_log);
      }
    }
  }

  void OnReceivedPli() override { received_pli_ = true; }

  PacketRef BuildRtcpPacketFromRtpReceiver(
      const RtcpTimeData& time_data,
      const RtcpCastMessage* cast_message,
      const RtcpPliMessage* pli_message,
      base::TimeDelta target_delay,
      const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events,
      const RtpReceiverStatistics* rtp_receiver_statistics) {
    RtcpBuilder builder(rtcp_at_rtp_receiver_.local_ssrc());
    builder.Start();
    RtcpReceiverReferenceTimeReport rrtr;
    rrtr.ntp_seconds = time_data.ntp_seconds;
    rrtr.ntp_fraction = time_data.ntp_fraction;
    builder.AddRrtr(rrtr);
    RtcpReportBlock report_block;
    if (rtp_receiver_statistics) {
      report_block.remote_ssrc = 0;
      report_block.media_ssrc = rtcp_at_rtp_receiver_.remote_ssrc();
      report_block.fraction_lost = rtp_receiver_statistics->fraction_lost;
      report_block.cumulative_lost = rtp_receiver_statistics->cumulative_lost;
      report_block.extended_high_sequence_number =
          rtp_receiver_statistics->extended_high_sequence_number;
      report_block.jitter = rtp_receiver_statistics->jitter;
      report_block.last_sr = rtcp_at_rtp_receiver_.last_report_truncated_ntp();
      base::TimeTicks last_report_received_time =
          rtcp_at_rtp_receiver_.time_last_report_received();
      if (!last_report_received_time.is_null()) {
        uint32_t delay_seconds = 0;
        uint32_t delay_fraction = 0;
        base::TimeDelta delta = time_data.timestamp - last_report_received_time;
        ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds,
                               &delay_fraction);
        report_block.delay_since_last_sr =
            ConvertToNtpDiff(delay_seconds, delay_fraction);
      } else {
        report_block.delay_since_last_sr = 0;
      }
      builder.AddRR(&report_block);
    }
    if (cast_message)
      builder.AddCast(*cast_message, target_delay);
    if (pli_message)
      builder.AddPli(*pli_message);
    if (rtcp_events)
      builder.AddReceiverLog(*rtcp_events);
    return builder.Finish();
  }

  std::unique_ptr<base::SimpleTestTickClock> sender_clock_;
  std::unique_ptr<test::SkewedTickClock> receiver_clock_;
  FakeRtcpTransport rtp_sender_pacer_;
  FakeRtcpTransport rtp_receiver_pacer_;
  SenderRtcpSession rtcp_at_rtp_sender_;
  ReceiverRtcpSession rtcp_at_rtp_receiver_;

  base::TimeDelta current_round_trip_time_;
  RtcpCastMessage last_cast_message_;
  RtcpReceiverLogMessage last_logs_;
  bool received_pli_;

 private:
  DISALLOW_COPY_AND_ASSIGN(RtcpTest);
};

TEST_F(RtcpTest, LipSyncGleanedFromSenderReport) {
  // Initially, expect no lip-sync info receiver-side without having first
  // received a RTCP packet.
  base::TimeTicks reference_time;
  RtpTimeTicks rtp_timestamp;
  ASSERT_FALSE(rtcp_at_rtp_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
                                                           &reference_time));

  // Send a Sender Report to the receiver.
  const base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
  const RtpTimeTicks rtp_timestamp_sent =
      RtpTimeTicks().Expand(UINT32_C(0xbee5));
  rtcp_at_rtp_sender_.SendRtcpReport(reference_time_sent, rtp_timestamp_sent, 1,
                                     1);

  // Now the receiver should have lip-sync info.  Confirm that the lip-sync
  // reference time is the same as that sent.
  EXPECT_TRUE(rtcp_at_rtp_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
                                                          &reference_time));
  const base::TimeTicks rolled_back_time =
      (reference_time -
       // Roll-back relative clock offset:
       base::Seconds(kInitialReceiverClockOffsetSeconds) -
       // Roll-back packet transmission time (because RTT is not yet known):
       rtp_sender_pacer_.packet_delay());
  EXPECT_NEAR(0, (reference_time_sent - rolled_back_time).InMicroseconds(), 5);
  EXPECT_EQ(rtp_timestamp_sent, rtp_timestamp);
}

TEST_F(RtcpTest, RoundTripTimesDeterminedFromReportPingPong) {
  const int iterations = 12;

  // Sender does not know the RTT yet.
  ASSERT_EQ(base::TimeDelta(), rtcp_at_rtp_sender_.current_round_trip_time());

  // Do a number of ping-pongs, checking how the round trip times are measured
  // by the sender.
  base::TimeDelta expected_rtt_according_to_sender;
  for (int i = 0; i < iterations; ++i) {
    const base::TimeDelta one_way_trip_time =
        base::Milliseconds(static_cast<int64_t>(1) << i);
    rtp_sender_pacer_.set_packet_delay(one_way_trip_time);
    rtp_receiver_pacer_.set_packet_delay(one_way_trip_time);

    // Sender --> Receiver
    base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
    const RtpTimeTicks rtp_timestamp_sent =
        RtpTimeTicks().Expand<uint32_t>(0xbee5) + RtpTimeDelta::FromTicks(i);
    rtcp_at_rtp_sender_.SendRtcpReport(reference_time_sent, rtp_timestamp_sent,
                                       1, 1);
    EXPECT_EQ(expected_rtt_according_to_sender,
              rtcp_at_rtp_sender_.current_round_trip_time());

    // Validate last reported callback value is same as that reported by method.
    EXPECT_EQ(current_round_trip_time_,
              rtcp_at_rtp_sender_.current_round_trip_time());

    // Receiver --> Sender
    RtpReceiverStatistics stats;
    rtp_receiver_pacer_.SendRtcpPacket(
        rtcp_at_rtp_receiver_.local_ssrc(),
        BuildRtcpPacketFromRtpReceiver(
            CreateRtcpTimeData(receiver_clock_->NowTicks()), nullptr, nullptr,
            base::TimeDelta(), nullptr, &stats));
    expected_rtt_according_to_sender = one_way_trip_time * 2;
    EXPECT_EQ(expected_rtt_according_to_sender,
              rtcp_at_rtp_sender_.current_round_trip_time());
  }
}

TEST_F(RtcpTest, ReportCastFeedback) {
  // Sender has sent all frames up to and including first+5.
  rtcp_at_rtp_sender_.WillSendFrame(FrameId::first() + 5);

  // ACK all frames up to and including first+5, except NACK a few in first+1
  // and first+2.
  RtcpCastMessage cast_message(kSenderSsrc);
  cast_message.ack_frame_id = FrameId::first() + 5;
  PacketIdSet missing_packets1 = {3, 4};
  cast_message.missing_frames_and_packets[FrameId::first() + 1] =
      missing_packets1;
  PacketIdSet missing_packets2 = {5, 6};
  cast_message.missing_frames_and_packets[FrameId::first() + 2] =
      missing_packets2;

  rtp_receiver_pacer_.SendRtcpPacket(
      rtcp_at_rtp_receiver_.local_ssrc(),
      BuildRtcpPacketFromRtpReceiver(
          CreateRtcpTimeData(base::TimeTicks()), &cast_message, nullptr,
          base::Milliseconds(kTargetDelayMs), nullptr, nullptr));

  EXPECT_EQ(last_cast_message_.ack_frame_id, cast_message.ack_frame_id);
  EXPECT_EQ(last_cast_message_.target_delay_ms, kTargetDelayMs);
  EXPECT_EQ(last_cast_message_.missing_frames_and_packets.size(),
            cast_message.missing_frames_and_packets.size());
  EXPECT_TRUE(
      std::equal(cast_message.missing_frames_and_packets.begin(),
                 cast_message.missing_frames_and_packets.end(),
                 last_cast_message_.missing_frames_and_packets.begin()));
}

TEST_F(RtcpTest, ReportPli) {
  RtcpPliMessage pli_message(kSenderSsrc);
  rtp_receiver_pacer_.SendRtcpPacket(
      rtcp_at_rtp_receiver_.local_ssrc(),
      BuildRtcpPacketFromRtpReceiver(CreateRtcpTimeData(base::TimeTicks()),
                                     nullptr, &pli_message, base::TimeDelta(),
                                     nullptr, nullptr));
  EXPECT_TRUE(received_pli_);
}

TEST_F(RtcpTest, DropLateRtcpPacket) {
  // Sender has sent all frames up to and including first+2.
  rtcp_at_rtp_sender_.WillSendFrame(FrameId::first() + 2);

  // Receiver ACKs first+1.
  RtcpCastMessage cast_message(kSenderSsrc);
  cast_message.ack_frame_id = FrameId::first() + 1;
  rtp_receiver_pacer_.SendRtcpPacket(
      rtcp_at_rtp_receiver_.local_ssrc(),
      BuildRtcpPacketFromRtpReceiver(
          CreateRtcpTimeData(receiver_clock_->NowTicks()), &cast_message,
          nullptr, base::Milliseconds(kTargetDelayMs), nullptr, nullptr));

  // Receiver ACKs first+2, but with a too-old timestamp.
  RtcpCastMessage late_cast_message(kSenderSsrc);
  late_cast_message.ack_frame_id = FrameId::first() + 2;
  rtp_receiver_pacer_.SendRtcpPacket(
      rtcp_at_rtp_receiver_.local_ssrc(),
      BuildRtcpPacketFromRtpReceiver(
          CreateRtcpTimeData(receiver_clock_->NowTicks() - base::Seconds(10)),
          &late_cast_message, nullptr, base::TimeDelta(), nullptr, nullptr));

  // Validate data from second packet is dropped.
  EXPECT_EQ(last_cast_message_.ack_frame_id, cast_message.ack_frame_id);
  EXPECT_EQ(last_cast_message_.target_delay_ms, kTargetDelayMs);

  // Re-send with fresh timestamp
  late_cast_message.ack_frame_id = FrameId::first() + 2;
  rtp_receiver_pacer_.SendRtcpPacket(
      rtcp_at_rtp_receiver_.local_ssrc(),
      BuildRtcpPacketFromRtpReceiver(
          CreateRtcpTimeData(receiver_clock_->NowTicks()), &late_cast_message,
          nullptr, base::TimeDelta(), nullptr, nullptr));
  EXPECT_EQ(last_cast_message_.ack_frame_id, late_cast_message.ack_frame_id);
  EXPECT_EQ(last_cast_message_.target_delay_ms, 0);
}

TEST_F(RtcpTest, ReportReceiverEvents) {
  const RtpTimeTicks kRtpTimeStamp =
      media::cast::RtpTimeTicks().Expand(UINT32_C(100));
  const base::TimeTicks kEventTimestamp = receiver_clock_->NowTicks();
  const base::TimeDelta kDelayDelta = base::Milliseconds(100);

  RtcpEvent event;
  event.type = FRAME_ACK_SENT;
  event.timestamp = kEventTimestamp;
  event.delay_delta = kDelayDelta;
  ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
  rtcp_events.push_back(std::make_pair(kRtpTimeStamp, event));

  rtp_receiver_pacer_.SendRtcpPacket(
      rtcp_at_rtp_receiver_.local_ssrc(),
      BuildRtcpPacketFromRtpReceiver(
          CreateRtcpTimeData(receiver_clock_->NowTicks()), nullptr, nullptr,
          base::TimeDelta(), &rtcp_events, nullptr));

  ASSERT_EQ(1UL, last_logs_.size());
  RtcpReceiverFrameLogMessage frame_log = last_logs_.front();
  EXPECT_EQ(frame_log.rtp_timestamp_, kRtpTimeStamp);

  ASSERT_EQ(1UL, frame_log.event_log_messages_.size());
  RtcpReceiverEventLogMessage log_msg = frame_log.event_log_messages_.back();
  EXPECT_EQ(log_msg.type, event.type);
  EXPECT_EQ(log_msg.delay_delta, event.delay_delta);
  // Only 24 bits of event timestamp sent on wire.
  uint32_t event_ts =
      (event.timestamp - base::TimeTicks()).InMilliseconds() & 0xffffff;
  uint32_t log_msg_ts =
      (log_msg.event_timestamp - base::TimeTicks()).InMilliseconds() & 0xffffff;
  EXPECT_EQ(log_msg_ts, event_ts);
}

}  // namespace cast
}  // namespace media
