/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <memory>
#include <string>

#include "webrtc/base/copyonwritebuffer.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/helpers.h"
#include "webrtc/base/ssladapter.h"
#include "webrtc/media/base/fakenetworkinterface.h"
#include "webrtc/media/base/mediaconstants.h"
#include "webrtc/media/base/rtpdataengine.h"
#include "webrtc/media/base/rtputils.h"

class FakeDataReceiver : public sigslot::has_slots<> {
 public:
  FakeDataReceiver() : has_received_data_(false) {}

  void OnDataReceived(
      const cricket::ReceiveDataParams& params,
      const char* data, size_t len) {
    has_received_data_ = true;
    last_received_data_ = std::string(data, len);
    last_received_data_len_ = len;
    last_received_data_params_ = params;
  }

  bool has_received_data() const { return has_received_data_; }
  std::string last_received_data() const { return last_received_data_; }
  size_t last_received_data_len() const { return last_received_data_len_; }
  cricket::ReceiveDataParams last_received_data_params() const {
    return last_received_data_params_;
  }

 private:
  bool has_received_data_;
  std::string last_received_data_;
  size_t last_received_data_len_;
  cricket::ReceiveDataParams last_received_data_params_;
};

class RtpDataMediaChannelTest : public testing::Test {
 protected:
  virtual void SetUp() {
    // Seed needed for each test to satisfy expectations.
    iface_.reset(new cricket::FakeNetworkInterface());
    dme_.reset(CreateEngine());
    receiver_.reset(new FakeDataReceiver());
  }

  void SetNow(double now) {
    clock_.SetTimeNanos(now * rtc::kNumNanosecsPerSec);
  }

  cricket::RtpDataEngine* CreateEngine() {
    cricket::RtpDataEngine* dme = new cricket::RtpDataEngine();
    return dme;
  }

  cricket::RtpDataMediaChannel* CreateChannel() {
    return CreateChannel(dme_.get());
  }

  cricket::RtpDataMediaChannel* CreateChannel(cricket::RtpDataEngine* dme) {
    cricket::RtpDataMediaChannel* channel =
        static_cast<cricket::RtpDataMediaChannel*>(dme->CreateChannel(
            cricket::DCT_RTP));
    channel->SetInterface(iface_.get());
    channel->SignalDataReceived.connect(
        receiver_.get(), &FakeDataReceiver::OnDataReceived);
    return channel;
  }

  FakeDataReceiver* receiver() {
    return receiver_.get();
  }

  bool HasReceivedData() {
    return receiver_->has_received_data();
  }

  std::string GetReceivedData() {
    return receiver_->last_received_data();
  }

  size_t GetReceivedDataLen() {
    return receiver_->last_received_data_len();
  }

  cricket::ReceiveDataParams GetReceivedDataParams() {
    return receiver_->last_received_data_params();
  }

  bool HasSentData(int count) {
    return (iface_->NumRtpPackets() > count);
  }

  std::string GetSentData(int index) {
    // Assume RTP header of length 12
    std::unique_ptr<const rtc::CopyOnWriteBuffer> packet(
        iface_->GetRtpPacket(index));
    if (packet->size() > 12) {
      return std::string(packet->data<char>() + 12, packet->size() - 12);
    } else {
      return "";
    }
  }

  cricket::RtpHeader GetSentDataHeader(int index) {
    std::unique_ptr<const rtc::CopyOnWriteBuffer> packet(
        iface_->GetRtpPacket(index));
    cricket::RtpHeader header;
    GetRtpHeader(packet->data(), packet->size(), &header);
    return header;
  }

 private:
  std::unique_ptr<cricket::RtpDataEngine> dme_;
  rtc::ScopedFakeClock clock_;
  std::unique_ptr<cricket::FakeNetworkInterface> iface_;
  std::unique_ptr<FakeDataReceiver> receiver_;
};

TEST_F(RtpDataMediaChannelTest, SetUnknownCodecs) {
  std::unique_ptr<cricket::RtpDataMediaChannel> dmc(CreateChannel());

  cricket::DataCodec known_codec;
  known_codec.id = 103;
  known_codec.name = "google-data";
  cricket::DataCodec unknown_codec;
  unknown_codec.id = 104;
  unknown_codec.name = "unknown-data";

  cricket::DataSendParameters send_parameters_known;
  send_parameters_known.codecs.push_back(known_codec);
  cricket::DataRecvParameters recv_parameters_known;
  recv_parameters_known.codecs.push_back(known_codec);

  cricket::DataSendParameters send_parameters_unknown;
  send_parameters_unknown.codecs.push_back(unknown_codec);
  cricket::DataRecvParameters recv_parameters_unknown;
  recv_parameters_unknown.codecs.push_back(unknown_codec);

  cricket::DataSendParameters send_parameters_mixed;
  send_parameters_mixed.codecs.push_back(known_codec);
  send_parameters_mixed.codecs.push_back(unknown_codec);
  cricket::DataRecvParameters recv_parameters_mixed;
  recv_parameters_mixed.codecs.push_back(known_codec);
  recv_parameters_mixed.codecs.push_back(unknown_codec);

  EXPECT_TRUE(dmc->SetSendParameters(send_parameters_known));
  EXPECT_FALSE(dmc->SetSendParameters(send_parameters_unknown));
  EXPECT_TRUE(dmc->SetSendParameters(send_parameters_mixed));
  EXPECT_TRUE(dmc->SetRecvParameters(recv_parameters_known));
  EXPECT_FALSE(dmc->SetRecvParameters(recv_parameters_unknown));
  EXPECT_FALSE(dmc->SetRecvParameters(recv_parameters_mixed));
}

TEST_F(RtpDataMediaChannelTest, AddRemoveSendStream) {
  std::unique_ptr<cricket::RtpDataMediaChannel> dmc(CreateChannel());

  cricket::StreamParams stream1;
  stream1.add_ssrc(41);
  EXPECT_TRUE(dmc->AddSendStream(stream1));
  cricket::StreamParams stream2;
  stream2.add_ssrc(42);
  EXPECT_TRUE(dmc->AddSendStream(stream2));

  EXPECT_TRUE(dmc->RemoveSendStream(41));
  EXPECT_TRUE(dmc->RemoveSendStream(42));
  EXPECT_FALSE(dmc->RemoveSendStream(43));
}

TEST_F(RtpDataMediaChannelTest, AddRemoveRecvStream) {
  std::unique_ptr<cricket::RtpDataMediaChannel> dmc(CreateChannel());

  cricket::StreamParams stream1;
  stream1.add_ssrc(41);
  EXPECT_TRUE(dmc->AddRecvStream(stream1));
  cricket::StreamParams stream2;
  stream2.add_ssrc(42);
  EXPECT_TRUE(dmc->AddRecvStream(stream2));
  EXPECT_FALSE(dmc->AddRecvStream(stream2));

  EXPECT_TRUE(dmc->RemoveRecvStream(41));
  EXPECT_TRUE(dmc->RemoveRecvStream(42));
}

TEST_F(RtpDataMediaChannelTest, SendData) {
  std::unique_ptr<cricket::RtpDataMediaChannel> dmc(CreateChannel());

  cricket::SendDataParams params;
  params.ssrc = 42;
  unsigned char data[] = "food";
  rtc::CopyOnWriteBuffer payload(data, 4);
  unsigned char padded_data[] = {
    0x00, 0x00, 0x00, 0x00,
    'f', 'o', 'o', 'd',
  };
  cricket::SendDataResult result;

  // Not sending
  EXPECT_FALSE(dmc->SendData(params, payload, &result));
  EXPECT_EQ(cricket::SDR_ERROR, result);
  EXPECT_FALSE(HasSentData(0));
  ASSERT_TRUE(dmc->SetSend(true));

  // Unknown stream name.
  EXPECT_FALSE(dmc->SendData(params, payload, &result));
  EXPECT_EQ(cricket::SDR_ERROR, result);
  EXPECT_FALSE(HasSentData(0));

  cricket::StreamParams stream;
  stream.add_ssrc(42);
  ASSERT_TRUE(dmc->AddSendStream(stream));

  // Unknown codec;
  EXPECT_FALSE(dmc->SendData(params, payload, &result));
  EXPECT_EQ(cricket::SDR_ERROR, result);
  EXPECT_FALSE(HasSentData(0));

  cricket::DataCodec codec;
  codec.id = 103;
  codec.name = cricket::kGoogleRtpDataCodecName;
  cricket::DataSendParameters parameters;
  parameters.codecs.push_back(codec);
  ASSERT_TRUE(dmc->SetSendParameters(parameters));

  // Length too large;
  std::string x10000(10000, 'x');
  EXPECT_FALSE(dmc->SendData(
      params, rtc::CopyOnWriteBuffer(x10000.data(), x10000.length()), &result));
  EXPECT_EQ(cricket::SDR_ERROR, result);
  EXPECT_FALSE(HasSentData(0));

  // Finally works!
  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  EXPECT_EQ(cricket::SDR_SUCCESS, result);
  ASSERT_TRUE(HasSentData(0));
  EXPECT_EQ(sizeof(padded_data), GetSentData(0).length());
  EXPECT_EQ(0, memcmp(
      padded_data, GetSentData(0).data(), sizeof(padded_data)));
  cricket::RtpHeader header0 = GetSentDataHeader(0);
  EXPECT_NE(0, header0.seq_num);
  EXPECT_NE(0U, header0.timestamp);
  EXPECT_EQ(header0.ssrc, 42U);
  EXPECT_EQ(header0.payload_type, 103);

  // Should bump timestamp by 180000 because the clock rate is 90khz.
  SetNow(2);

  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  ASSERT_TRUE(HasSentData(1));
  EXPECT_EQ(sizeof(padded_data), GetSentData(1).length());
  EXPECT_EQ(0, memcmp(
      padded_data, GetSentData(1).data(), sizeof(padded_data)));
  cricket::RtpHeader header1 = GetSentDataHeader(1);
  EXPECT_EQ(header1.ssrc, 42U);
  EXPECT_EQ(header1.payload_type, 103);
  EXPECT_EQ(static_cast<uint16_t>(header0.seq_num + 1),
            static_cast<uint16_t>(header1.seq_num));
  EXPECT_EQ(header0.timestamp + 180000, header1.timestamp);
}

TEST_F(RtpDataMediaChannelTest, SendDataRate) {
  std::unique_ptr<cricket::RtpDataMediaChannel> dmc(CreateChannel());

  ASSERT_TRUE(dmc->SetSend(true));

  cricket::DataCodec codec;
  codec.id = 103;
  codec.name = cricket::kGoogleRtpDataCodecName;
  cricket::DataSendParameters parameters;
  parameters.codecs.push_back(codec);
  ASSERT_TRUE(dmc->SetSendParameters(parameters));

  cricket::StreamParams stream;
  stream.add_ssrc(42);
  ASSERT_TRUE(dmc->AddSendStream(stream));

  cricket::SendDataParams params;
  params.ssrc = 42;
  unsigned char data[] = "food";
  rtc::CopyOnWriteBuffer payload(data, 4);
  cricket::SendDataResult result;

  // With rtp overhead of 32 bytes, each one of our packets is 36
  // bytes, or 288 bits.  So, a limit of 872bps will allow 3 packets,
  // but not four.
  parameters.max_bandwidth_bps = 872;
  ASSERT_TRUE(dmc->SetSendParameters(parameters));

  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  EXPECT_FALSE(dmc->SendData(params, payload, &result));
  EXPECT_FALSE(dmc->SendData(params, payload, &result));

  SetNow(0.9);
  EXPECT_FALSE(dmc->SendData(params, payload, &result));

  SetNow(1.1);
  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  SetNow(1.9);
  EXPECT_TRUE(dmc->SendData(params, payload, &result));

  SetNow(2.2);
  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  EXPECT_TRUE(dmc->SendData(params, payload, &result));
  EXPECT_FALSE(dmc->SendData(params, payload, &result));
}

TEST_F(RtpDataMediaChannelTest, ReceiveData) {
  // PT= 103, SN=2, TS=3, SSRC = 4, data = "abcde"
  unsigned char data[] = {
    0x80, 0x67, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2A,
    0x00, 0x00, 0x00, 0x00,
    'a', 'b', 'c', 'd', 'e'
  };
  rtc::CopyOnWriteBuffer packet(data, sizeof(data));

  std::unique_ptr<cricket::RtpDataMediaChannel> dmc(CreateChannel());

  // SetReceived not called.
  dmc->OnPacketReceived(&packet, rtc::PacketTime());
  EXPECT_FALSE(HasReceivedData());

  dmc->SetReceive(true);

  // Unknown payload id
  dmc->OnPacketReceived(&packet, rtc::PacketTime());
  EXPECT_FALSE(HasReceivedData());

  cricket::DataCodec codec;
  codec.id = 103;
  codec.name = cricket::kGoogleRtpDataCodecName;
  cricket::DataRecvParameters parameters;
  parameters.codecs.push_back(codec);
  ASSERT_TRUE(dmc->SetRecvParameters(parameters));

  // Unknown stream
  dmc->OnPacketReceived(&packet, rtc::PacketTime());
  EXPECT_FALSE(HasReceivedData());

  cricket::StreamParams stream;
  stream.add_ssrc(42);
  ASSERT_TRUE(dmc->AddRecvStream(stream));

  // Finally works!
  dmc->OnPacketReceived(&packet, rtc::PacketTime());
  EXPECT_TRUE(HasReceivedData());
  EXPECT_EQ("abcde", GetReceivedData());
  EXPECT_EQ(5U, GetReceivedDataLen());
}

TEST_F(RtpDataMediaChannelTest, InvalidRtpPackets) {
  unsigned char data[] = {
    0x80, 0x65, 0x00, 0x02
  };
  rtc::CopyOnWriteBuffer packet(data, sizeof(data));

  std::unique_ptr<cricket::RtpDataMediaChannel> dmc(CreateChannel());

  // Too short
  dmc->OnPacketReceived(&packet, rtc::PacketTime());
  EXPECT_FALSE(HasReceivedData());
}
