// 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 <gtest/gtest.h>
#include <stdint.h>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/scoped_ptr.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/values.h"
#include "media/cast/cast_config.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/cast_transport_sender_impl.h"
#include "media/cast/net/rtcp/rtcp.h"
#include "media/cast/test/fake_single_thread_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {
namespace cast {

namespace {
const int64 kStartMillisecond = INT64_C(12345678900000);
const uint32 kVideoSsrc = 1;
const uint32 kAudioSsrc = 2;
}  // namespace

class FakePacketSender : public PacketSender {
 public:
  FakePacketSender()
      : paused_(false), packets_sent_(0), bytes_sent_(0) {}

  bool SendPacket(PacketRef packet, const base::Closure& cb) override {
    if (paused_) {
      stored_packet_ = packet;
      callback_ = cb;
      return false;
    }
    ++packets_sent_;
    bytes_sent_ += packet->data.size();
    return true;
  }

  int64 GetBytesSent() override { return bytes_sent_; }

  void SetPaused(bool paused) {
    paused_ = paused;
    if (!paused && stored_packet_.get()) {
      SendPacket(stored_packet_, callback_);
      callback_.Run();
    }
  }

  int packets_sent() const { return packets_sent_; }

 private:
  bool paused_;
  base::Closure callback_;
  PacketRef stored_packet_;
  int packets_sent_;
  int64 bytes_sent_;

  DISALLOW_COPY_AND_ASSIGN(FakePacketSender);
};

class CastTransportSenderImplTest : public ::testing::Test {
 protected:
  CastTransportSenderImplTest()
      : num_times_callback_called_(0) {
    testing_clock_.Advance(
        base::TimeDelta::FromMilliseconds(kStartMillisecond));
    task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_);
  }

  ~CastTransportSenderImplTest() override {}

  void InitWithoutLogging() {
    transport_sender_.reset(
        new CastTransportSenderImpl(NULL,
                                    &testing_clock_,
                                    net::IPEndPoint(),
                                    make_scoped_ptr(new base::DictionaryValue),
                                    base::Bind(&UpdateCastTransportStatus),
                                    BulkRawEventsCallback(),
                                    base::TimeDelta(),
                                    task_runner_,
                                    &transport_));
    task_runner_->RunTasks();
  }

  void InitWithOptions() {
    scoped_ptr<base::DictionaryValue> options(
        new base::DictionaryValue);
    options->SetBoolean("DHCP", true);
    options->SetBoolean("disable_wifi_scan", true);
    options->SetBoolean("media_streaming_mode", true);
    options->SetInteger("pacer_target_burst_size", 20);
    options->SetInteger("pacer_max_burst_size", 100);
    transport_sender_.reset(
        new CastTransportSenderImpl(NULL,
                                    &testing_clock_,
                                    net::IPEndPoint(),
                                    options.Pass(),
                                    base::Bind(&UpdateCastTransportStatus),
                                    BulkRawEventsCallback(),
                                    base::TimeDelta(),
                                    task_runner_,
                                    &transport_));
    task_runner_->RunTasks();
  }

  void InitWithLogging() {
    transport_sender_.reset(new CastTransportSenderImpl(
        NULL,
        &testing_clock_,
        net::IPEndPoint(),
        make_scoped_ptr(new base::DictionaryValue),
        base::Bind(&UpdateCastTransportStatus),
        base::Bind(&CastTransportSenderImplTest::LogRawEvents,
                   base::Unretained(this)),
        base::TimeDelta::FromMilliseconds(10),
        task_runner_,
        &transport_));
    task_runner_->RunTasks();
  }

  void InitializeVideo() {
    CastTransportRtpConfig rtp_config;
    rtp_config.ssrc = kVideoSsrc;
    rtp_config.feedback_ssrc = 2;
    rtp_config.rtp_payload_type = 3;
    transport_sender_->InitializeVideo(rtp_config,
                                       RtcpCastMessageCallback(),
                                       RtcpRttCallback());
  }

  void InitializeAudio() {
    CastTransportRtpConfig rtp_config;
    rtp_config.ssrc = kAudioSsrc;
    rtp_config.feedback_ssrc = 3;
    rtp_config.rtp_payload_type = 4;
    transport_sender_->InitializeAudio(rtp_config,
                                       RtcpCastMessageCallback(),
                                       RtcpRttCallback());
  }

  void LogRawEvents(const std::vector<PacketEvent>& packet_events,
                    const std::vector<FrameEvent>& frame_events) {
    num_times_callback_called_++;
  }

  static void UpdateCastTransportStatus(CastTransportStatus status) {
  }

  base::SimpleTestTickClock testing_clock_;
  scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
  scoped_ptr<CastTransportSenderImpl> transport_sender_;
  FakePacketSender transport_;
  int num_times_callback_called_;
};

TEST_F(CastTransportSenderImplTest, InitWithoutLogging) {
  InitWithoutLogging();
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));
  EXPECT_EQ(0, num_times_callback_called_);
}

TEST_F(CastTransportSenderImplTest, InitWithLogging) {
  InitWithLogging();
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));
  EXPECT_EQ(5, num_times_callback_called_);
}

TEST_F(CastTransportSenderImplTest, InitWithOptions) {
  InitWithOptions();
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));
  EXPECT_EQ(0, num_times_callback_called_);
}

TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) {
  InitWithoutLogging();
  InitializeVideo();
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));

  // A fake frame that will be decomposed into 4 packets.
  EncodedFrame fake_frame;
  fake_frame.frame_id = 1;
  fake_frame.rtp_timestamp = 1;
  fake_frame.dependency = EncodedFrame::KEY;
  fake_frame.data.resize(5000, ' ');

  transport_sender_->InsertFrame(kVideoSsrc, fake_frame);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
  EXPECT_EQ(4, transport_.packets_sent());

  // Resend packet 0.
  MissingFramesAndPacketsMap missing_packets;
  missing_packets[1].insert(0);
  missing_packets[1].insert(1);
  missing_packets[1].insert(2);

  transport_.SetPaused(true);
  DedupInfo dedup_info;
  dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
  transport_sender_->ResendPackets(
      kVideoSsrc, missing_packets, true, dedup_info);

  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));

  RtcpCastMessage cast_message;
  cast_message.media_ssrc = kVideoSsrc;
  cast_message.ack_frame_id = 1;
  cast_message.missing_frames_and_packets[1].insert(3);
  transport_sender_->OnReceivedCastMessage(kVideoSsrc,
                                           RtcpCastMessageCallback(),
                                           cast_message);
  transport_.SetPaused(false);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));

  // Resend one packet in the socket when unpaused.
  // Resend one more packet from NACK.
  EXPECT_EQ(6, transport_.packets_sent());
}

TEST_F(CastTransportSenderImplTest, CancelRetransmits) {
  InitWithoutLogging();
  InitializeVideo();
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));

  // A fake frame that will be decomposed into 4 packets.
  EncodedFrame fake_frame;
  fake_frame.frame_id = 1;
  fake_frame.rtp_timestamp = 1;
  fake_frame.dependency = EncodedFrame::KEY;
  fake_frame.data.resize(5000, ' ');

  transport_sender_->InsertFrame(kVideoSsrc, fake_frame);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
  EXPECT_EQ(4, transport_.packets_sent());

  // Resend all packets for frame 1.
  MissingFramesAndPacketsMap missing_packets;
  missing_packets[1].insert(kRtcpCastAllPacketsLost);

  transport_.SetPaused(true);
  DedupInfo dedup_info;
  dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
  transport_sender_->ResendPackets(
      kVideoSsrc, missing_packets, true, dedup_info);

  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
  std::vector<uint32> cancel_sending_frames;
  cancel_sending_frames.push_back(1);
  transport_sender_->CancelSendingFrames(kVideoSsrc,
                                         cancel_sending_frames);
  transport_.SetPaused(false);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));

  // Resend one packet in the socket when unpaused.
  EXPECT_EQ(5, transport_.packets_sent());
}

TEST_F(CastTransportSenderImplTest, Kickstart) {
  InitWithoutLogging();
  InitializeVideo();
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));

  // A fake frame that will be decomposed into 4 packets.
  EncodedFrame fake_frame;
  fake_frame.frame_id = 1;
  fake_frame.rtp_timestamp = 1;
  fake_frame.dependency = EncodedFrame::KEY;
  fake_frame.data.resize(5000, ' ');

  transport_.SetPaused(true);
  transport_sender_->InsertFrame(kVideoSsrc, fake_frame);
  transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1);
  transport_.SetPaused(false);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
  EXPECT_EQ(4, transport_.packets_sent());

  // Resend 2 packets for frame 1.
  MissingFramesAndPacketsMap missing_packets;
  missing_packets[1].insert(0);
  missing_packets[1].insert(1);

  transport_.SetPaused(true);
  DedupInfo dedup_info;
  dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
  transport_sender_->ResendPackets(
      kVideoSsrc, missing_packets, true, dedup_info);
  transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1);
  transport_.SetPaused(false);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));

  // Resend one packet in the socket when unpaused.
  // Two more retransmission packets sent.
  EXPECT_EQ(7, transport_.packets_sent());
}

TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
  InitWithoutLogging();
  InitializeAudio();
  InitializeVideo();
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));

  // Send two audio frames.
  EncodedFrame fake_audio;
  fake_audio.frame_id = 1;
  fake_audio.reference_time = testing_clock_.NowTicks();
  fake_audio.dependency = EncodedFrame::KEY;
  fake_audio.data.resize(100, ' ');
  transport_sender_->InsertFrame(kAudioSsrc, fake_audio);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
  fake_audio.frame_id = 2;
  fake_audio.reference_time = testing_clock_.NowTicks();
  transport_sender_->InsertFrame(kAudioSsrc, fake_audio);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
  EXPECT_EQ(2, transport_.packets_sent());

  // Ack the first audio frame.
  RtcpCastMessage cast_message;
  cast_message.media_ssrc = kAudioSsrc;
  cast_message.ack_frame_id = 1;
  transport_sender_->OnReceivedCastMessage(kAudioSsrc,
                                           RtcpCastMessageCallback(),
                                           cast_message);
  task_runner_->RunTasks();
  EXPECT_EQ(2, transport_.packets_sent());

  // Send a fake video frame that will be decomposed into 4 packets.
  EncodedFrame fake_video;
  fake_video.frame_id = 1;
  fake_video.dependency = EncodedFrame::KEY;
  fake_video.data.resize(5000, ' ');
  transport_sender_->InsertFrame(kVideoSsrc, fake_video);
  task_runner_->RunTasks();
  EXPECT_EQ(6, transport_.packets_sent());

  // Retransmission is reject because audio is not acked yet.
  cast_message.media_ssrc = kVideoSsrc;
  cast_message.ack_frame_id = 0;
  cast_message.missing_frames_and_packets[1].insert(3);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
  transport_sender_->OnReceivedCastMessage(kVideoSsrc,
                                           RtcpCastMessageCallback(),
                                           cast_message);
  task_runner_->RunTasks();
  EXPECT_EQ(6, transport_.packets_sent());

  // Ack the second audio frame.
  cast_message.media_ssrc = kAudioSsrc;
  cast_message.ack_frame_id = 2;
  cast_message.missing_frames_and_packets.clear();
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
  transport_sender_->OnReceivedCastMessage(kAudioSsrc,
                                           RtcpCastMessageCallback(),
                                           cast_message);
  task_runner_->RunTasks();
  EXPECT_EQ(6, transport_.packets_sent());

  // Retransmission of video packet now accepted.
  cast_message.media_ssrc = kVideoSsrc;
  cast_message.ack_frame_id = 1;
  cast_message.missing_frames_and_packets[1].insert(3);
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
  transport_sender_->OnReceivedCastMessage(kVideoSsrc,
                                           RtcpCastMessageCallback(),
                                           cast_message);
  task_runner_->RunTasks();
  EXPECT_EQ(7, transport_.packets_sent());
}

}  // namespace cast
}  // namespace media
