// 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 "media/cast/net/rtcp/rtcp_builder.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/macros.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/cast/cast_environment.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/cast_transport_defines.h"
#include "media/cast/net/pacing/paced_sender.h"
#include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h"
#include "media/cast/net/rtcp/rtcp_utility.h"
#include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace media {
namespace cast {

namespace {
static const uint32_t kSendingSsrc = 0x12345678;
static const uint32_t kMediaSsrc = 0x87654321;
static const base::TimeDelta kDefaultDelay = base::Milliseconds(100);

RtcpReportBlock GetReportBlock() {
  RtcpReportBlock report_block;
  // Initialize remote_ssrc to a "clearly illegal" value.
  report_block.remote_ssrc = 0xDEAD;
  report_block.media_ssrc = kMediaSsrc;  // SSRC of the RTP packet sender.
  report_block.fraction_lost = kLoss >> 24;
  report_block.cumulative_lost = kLoss;  // 24 bits valid.
  report_block.extended_high_sequence_number = kExtendedMax;
  report_block.jitter = kTestJitter;
  report_block.last_sr = kLastSr;
  report_block.delay_since_last_sr = kDelayLastSr;
  return report_block;
}

}  // namespace


class RtcpBuilderTest : public ::testing::Test {
 protected:
  RtcpBuilderTest()
      : rtcp_builder_(new RtcpBuilder(kSendingSsrc)) {}

  void ExpectPacketEQ(std::unique_ptr<Packet> golden_packet, PacketRef packet) {
    int diffs = 0;
    EXPECT_EQ(golden_packet->size(), packet->data.size());
    if (golden_packet->size() == packet->data.size()) {
      for (size_t x = 0; x < golden_packet->size(); x++) {
        EXPECT_EQ((*golden_packet)[x], packet->data[x]) <<
            "x = " << x << " / " << golden_packet->size();
        if ((*golden_packet)[x] != packet->data[x]) {
          if (++diffs > 5)
            break;
        }
      }
    }
  }

  static RtpTimeTicks test_rtp_timestamp() {
    return RtpTimeTicks().Expand(kRtpTimestamp);
  }

  PacketRef BuildRtcpFromReceiver(
      const RtcpReportBlock* report_block,
      const RtcpReceiverReferenceTimeReport* rrtr,
      const RtcpCastMessage* cast_message,
      const RtcpPliMessage* pli_message,
      const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events,
      base::TimeDelta target_delay) {
    DCHECK(rtcp_builder_);

    rtcp_builder_->Start();
    if (report_block)
      rtcp_builder_->AddRR(report_block);
    if (rrtr)
      rtcp_builder_->AddRrtr(*rrtr);
    if (cast_message)
      rtcp_builder_->AddCast(*cast_message, target_delay);
    if (pli_message)
      rtcp_builder_->AddPli(*pli_message);
    if (rtcp_events)
      rtcp_builder_->AddReceiverLog(*rtcp_events);
    return rtcp_builder_->Finish();
  }

  std::unique_ptr<RtcpBuilder> rtcp_builder_;

  DISALLOW_COPY_AND_ASSIGN(RtcpBuilderTest);
};

TEST_F(RtcpBuilderTest, RtcpReceiverReport) {
  // Receiver report with report block.
  TestRtcpPacketBuilder p2;
  p2.AddRr(kSendingSsrc, 1);
  p2.AddRb(kMediaSsrc);

  RtcpReportBlock report_block = GetReportBlock();

  ExpectPacketEQ(p2.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, nullptr, nullptr, nullptr,
                                       nullptr, kDefaultDelay));
}

TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtr) {
  // Receiver report with report block.
  TestRtcpPacketBuilder p;
  p.AddRr(kSendingSsrc, 1);
  p.AddRb(kMediaSsrc);
  p.AddXrHeader(kSendingSsrc);
  p.AddXrRrtrBlock();

  RtcpReportBlock report_block = GetReportBlock();

  RtcpReceiverReferenceTimeReport rrtr;
  rrtr.ntp_seconds = kNtpHigh;
  rrtr.ntp_fraction = kNtpLow;

  ExpectPacketEQ(p.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, &rrtr, nullptr, nullptr,
                                       nullptr, kDefaultDelay));
}

TEST_F(RtcpBuilderTest, RtcpReceiverReportWithCast) {
  // Receiver report with report block.
  TestRtcpPacketBuilder p;
  p.AddRr(kSendingSsrc, 1);
  p.AddRb(kMediaSsrc);
  p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);

  RtcpReportBlock report_block = GetReportBlock();

  RtcpCastMessage cast_message(kMediaSsrc);
  cast_message.ack_frame_id = FrameId::first() + kAckFrameId;
  PacketIdSet missing_packets;
  cast_message.missing_frames_and_packets[FrameId::first() + kLostFrameId] =
      missing_packets;

  missing_packets.insert(kLostPacketId1);
  missing_packets.insert(kLostPacketId2);
  missing_packets.insert(kLostPacketId3);
  cast_message
      .missing_frames_and_packets[FrameId::first() + kFrameIdWithLostPackets] =
      missing_packets;

  ExpectPacketEQ(p.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, nullptr, &cast_message,
                                       nullptr, nullptr, kDefaultDelay));
}

TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtraAndCastMessage) {
  TestRtcpPacketBuilder p;
  p.AddRr(kSendingSsrc, 1);
  p.AddRb(kMediaSsrc);
  p.AddXrHeader(kSendingSsrc);
  p.AddXrRrtrBlock();
  p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);

  RtcpReportBlock report_block = GetReportBlock();

  RtcpReceiverReferenceTimeReport rrtr;
  rrtr.ntp_seconds = kNtpHigh;
  rrtr.ntp_fraction = kNtpLow;

  RtcpCastMessage cast_message(kMediaSsrc);
  cast_message.ack_frame_id = FrameId::first() + kAckFrameId;
  PacketIdSet missing_packets;
  cast_message.missing_frames_and_packets[FrameId::first() + kLostFrameId] =
      missing_packets;

  missing_packets.insert(kLostPacketId1);
  missing_packets.insert(kLostPacketId2);
  missing_packets.insert(kLostPacketId3);
  cast_message
      .missing_frames_and_packets[FrameId::first() + kFrameIdWithLostPackets] =
      missing_packets;

  ExpectPacketEQ(p.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, &rrtr, &cast_message,
                                       nullptr, nullptr, kDefaultDelay));
}

TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) {
  static const uint32_t kTimeBaseMs = 12345678;
  static const uint32_t kTimeDelayMs = 10;

  TestRtcpPacketBuilder p;
  p.AddRr(kSendingSsrc, 1);
  p.AddRb(kMediaSsrc);
  p.AddXrHeader(kSendingSsrc);
  p.AddXrRrtrBlock();
  p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);

  RtcpReportBlock report_block = GetReportBlock();

  RtcpReceiverReferenceTimeReport rrtr;
  rrtr.ntp_seconds = kNtpHigh;
  rrtr.ntp_fraction = kNtpLow;

  RtcpCastMessage cast_message(kMediaSsrc);
  cast_message.ack_frame_id = FrameId::first() + kAckFrameId;
  PacketIdSet missing_packets;
  cast_message.missing_frames_and_packets[FrameId::first() + kLostFrameId] =
      missing_packets;

  missing_packets.insert(kLostPacketId1);
  missing_packets.insert(kLostPacketId2);
  missing_packets.insert(kLostPacketId3);
  cast_message
      .missing_frames_and_packets[FrameId::first() + kFrameIdWithLostPackets] =
      missing_packets;

  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
  ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;

  ExpectPacketEQ(p.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, &rrtr, &cast_message,
                                       nullptr, &rtcp_events, kDefaultDelay));

  base::SimpleTestTickClock testing_clock;
  testing_clock.Advance(base::Milliseconds(kTimeBaseMs));

  p.AddReceiverLog(kSendingSsrc);
  p.AddReceiverFrameLog(test_rtp_timestamp().lower_32_bits(), 2, kTimeBaseMs);
  p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
  p.AddReceiverEventLog(kLostPacketId1, PACKET_RECEIVED, kTimeDelayMs);

  FrameEvent frame_event;
  frame_event.rtp_timestamp = test_rtp_timestamp();
  frame_event.type = FRAME_ACK_SENT;
  frame_event.media_type = VIDEO_EVENT;
  frame_event.timestamp = testing_clock.NowTicks();
  event_subscriber.OnReceiveFrameEvent(frame_event);
  testing_clock.Advance(base::Milliseconds(kTimeDelayMs));

  PacketEvent packet_event;
  packet_event.rtp_timestamp = test_rtp_timestamp();
  packet_event.type = PACKET_RECEIVED;
  packet_event.media_type = VIDEO_EVENT;
  packet_event.timestamp = testing_clock.NowTicks();
  packet_event.packet_id = kLostPacketId1;
  event_subscriber.OnReceivePacketEvent(packet_event);
  event_subscriber.GetRtcpEventsWithRedundancy(&rtcp_events);
  EXPECT_EQ(2u, rtcp_events.size());

  ExpectPacketEQ(p.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, &rrtr, &cast_message,
                                       nullptr, &rtcp_events, kDefaultDelay));
}

TEST_F(RtcpBuilderTest, RtcpReceiverReportWithOversizedFrameLog) {
  static const uint32_t kTimeBaseMs = 12345678;
  static const uint32_t kTimeDelayMs = 10;

  TestRtcpPacketBuilder p;
  p.AddRr(kSendingSsrc, 1);
  p.AddRb(kMediaSsrc);

  RtcpReportBlock report_block = GetReportBlock();

  base::SimpleTestTickClock testing_clock;
  testing_clock.Advance(base::Milliseconds(kTimeBaseMs));

  p.AddReceiverLog(kSendingSsrc);

  int num_events = kMaxEventsPerRTCP;

  EXPECT_LE(num_events, static_cast<int>(kRtcpMaxReceiverLogMessages));
  p.AddReceiverFrameLog(
      (test_rtp_timestamp() + RtpTimeDelta::FromTicks(2345)).lower_32_bits(),
      num_events,
      kTimeBaseMs);
  for (int i = 0; i < num_events; i++) {
    p.AddReceiverEventLog(kLostPacketId1, PACKET_RECEIVED,
                          static_cast<uint16_t>(kTimeDelayMs * i));
  }


  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);

  for (size_t i = 0; i < kRtcpMaxReceiverLogMessages; ++i) {
    PacketEvent packet_event;
    packet_event.rtp_timestamp =
        test_rtp_timestamp() + RtpTimeDelta::FromTicks(2345);
    packet_event.type = PACKET_RECEIVED;
    packet_event.media_type = VIDEO_EVENT;
    packet_event.timestamp = testing_clock.NowTicks();
    packet_event.packet_id = kLostPacketId1;
    event_subscriber.OnReceivePacketEvent(packet_event);
    testing_clock.Advance(base::Milliseconds(kTimeDelayMs));
  }

  ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
  event_subscriber.GetRtcpEventsWithRedundancy(&rtcp_events);

  ExpectPacketEQ(p.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, nullptr, nullptr, nullptr,
                                       &rtcp_events, kDefaultDelay));
}

TEST_F(RtcpBuilderTest, RtcpReceiverReportWithTooManyLogFrames) {
  static const uint32_t kTimeBaseMs = 12345678;
  static const uint32_t kTimeDelayMs = 10;

  TestRtcpPacketBuilder p;
  p.AddRr(kSendingSsrc, 1);
  p.AddRb(kMediaSsrc);

  RtcpReportBlock report_block = GetReportBlock();

  base::SimpleTestTickClock testing_clock;
  testing_clock.Advance(base::Milliseconds(kTimeBaseMs));

  p.AddReceiverLog(kSendingSsrc);

  int num_events = kMaxEventsPerRTCP;

  for (int i = 0; i < num_events; i++) {
    p.AddReceiverFrameLog(
        (test_rtp_timestamp() + RtpTimeDelta::FromTicks(i)).lower_32_bits(),
        1, kTimeBaseMs + i * kTimeDelayMs);
    p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
  }

  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);

  for (size_t i = 0; i < kRtcpMaxReceiverLogMessages; ++i) {
    FrameEvent frame_event;
    frame_event.rtp_timestamp =
        test_rtp_timestamp() + RtpTimeDelta::FromTicks(i);
    frame_event.type = FRAME_ACK_SENT;
    frame_event.media_type = VIDEO_EVENT;
    frame_event.timestamp = testing_clock.NowTicks();
    event_subscriber.OnReceiveFrameEvent(frame_event);
    testing_clock.Advance(base::Milliseconds(kTimeDelayMs));
  }

  ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
  event_subscriber.GetRtcpEventsWithRedundancy(&rtcp_events);

  ExpectPacketEQ(p.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, nullptr, nullptr, nullptr,
                                       &rtcp_events, kDefaultDelay));
}

TEST_F(RtcpBuilderTest, RtcpReceiverReportWithOldLogFrames) {
  static const uint32_t kTimeBaseMs = 12345678;

  TestRtcpPacketBuilder p;
  p.AddRr(kSendingSsrc, 1);
  p.AddRb(kMediaSsrc);

  RtcpReportBlock report_block = GetReportBlock();

  base::SimpleTestTickClock testing_clock;
  testing_clock.Advance(base::Milliseconds(kTimeBaseMs));

  p.AddReceiverLog(kSendingSsrc);

  // Log 11 events for a single frame, each |kTimeBetweenEventsMs| apart.
  // Only last 10 events will be sent because the first event is more than
  // 4095 milliseconds away from latest event.
  const int kTimeBetweenEventsMs = 410;
  p.AddReceiverFrameLog(test_rtp_timestamp().lower_32_bits(), 10,
                        kTimeBaseMs + kTimeBetweenEventsMs);
  for (int i = 0; i < 10; ++i) {
    p.AddReceiverEventLog(0, FRAME_ACK_SENT, i * kTimeBetweenEventsMs);
  }

  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
  for (int i = 0; i < 11; ++i) {
    FrameEvent frame_event;
    frame_event.rtp_timestamp = test_rtp_timestamp();
    frame_event.type = FRAME_ACK_SENT;
    frame_event.media_type = VIDEO_EVENT;
    frame_event.timestamp = testing_clock.NowTicks();
    event_subscriber.OnReceiveFrameEvent(frame_event);
    testing_clock.Advance(base::Milliseconds(kTimeBetweenEventsMs));
  }

  ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
  event_subscriber.GetRtcpEventsWithRedundancy(&rtcp_events);

  ExpectPacketEQ(p.GetPacket(),
                 BuildRtcpFromReceiver(&report_block, nullptr, nullptr, nullptr,
                                       &rtcp_events, kDefaultDelay));
}

TEST_F(RtcpBuilderTest, RtcpReceiverReportRedundancy) {
  uint32_t time_base_ms = 12345678;
  int kTimeBetweenEventsMs = 10;

  RtcpReportBlock report_block = GetReportBlock();

  base::SimpleTestTickClock testing_clock;
  testing_clock.Advance(base::Milliseconds(time_base_ms));

  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
  size_t packet_count = kNumResends * kResendDelay + 10;
  for (size_t i = 0; i < packet_count; i++) {
    TestRtcpPacketBuilder p;
    p.AddRr(kSendingSsrc, 1);
    p.AddRb(kMediaSsrc);

    p.AddReceiverLog(kSendingSsrc);

    int num_events = (i + kResendDelay) / kResendDelay;
    num_events = std::min<int>(num_events, kNumResends);
    p.AddReceiverFrameLog(test_rtp_timestamp().lower_32_bits(), num_events,
        time_base_ms - (num_events - 1) * kResendDelay *
        kTimeBetweenEventsMs);
    for (int event = 0; event < num_events; event++) {
      p.AddReceiverEventLog(0, FRAME_ACK_SENT,
                            base::checked_cast<uint16_t>(event * kResendDelay *
                                                         kTimeBetweenEventsMs));
    }

    FrameEvent frame_event;
    frame_event.rtp_timestamp = test_rtp_timestamp();
    frame_event.type = FRAME_ACK_SENT;
    frame_event.media_type = VIDEO_EVENT;
    frame_event.timestamp = testing_clock.NowTicks();
    event_subscriber.OnReceiveFrameEvent(frame_event);

    ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
    event_subscriber.GetRtcpEventsWithRedundancy(&rtcp_events);

    ExpectPacketEQ(p.GetPacket(),
                   BuildRtcpFromReceiver(&report_block, nullptr, nullptr,
                                         nullptr, &rtcp_events, kDefaultDelay));

    testing_clock.Advance(base::Milliseconds(kTimeBetweenEventsMs));
    time_base_ms += kTimeBetweenEventsMs;
  }
}

TEST_F(RtcpBuilderTest, RtcpSenderReport) {
  RtcpSenderInfo sender_info;
  sender_info.ntp_seconds = kNtpHigh;
  sender_info.ntp_fraction = kNtpLow;
  sender_info.rtp_timestamp = test_rtp_timestamp();
  sender_info.send_packet_count = kSendPacketCount;
  sender_info.send_octet_count = kSendOctetCount;

  // Sender report.
  TestRtcpPacketBuilder p;
  p.AddSr(kSendingSsrc, 0);

  ExpectPacketEQ(p.GetPacket(),
                 rtcp_builder_->BuildRtcpFromSender(sender_info));
}

}  // namespace cast
}  // namespace media
