/*
 * libjingle
 * Copyright 2004 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <set>

#include "talk/media/base/filemediaengine.h"
#include "talk/media/base/rtpdump.h"
#include "talk/media/base/streamparams.h"
#include "talk/media/base/testutils.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/helpers.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/stream.h"

namespace cricket {

static const int kWaitTimeMs = 100;
static const std::string kFakeFileName = "foobar";

//////////////////////////////////////////////////////////////////////////////
// Media channel sends RTP packets via NetworkInterface. Rather than sending
// packets to the network, FileNetworkInterface writes packets to a stream and
// feeds packets back to the channel via OnPacketReceived.
//////////////////////////////////////////////////////////////////////////////
class FileNetworkInterface : public MediaChannel::NetworkInterface {
 public:
  FileNetworkInterface(rtc::StreamInterface* output, MediaChannel* ch)
      : media_channel_(ch),
        num_sent_packets_(0) {
    if (output) {
      dump_writer_.reset(new RtpDumpWriter(output));
    }
  }

  // Implement pure virtual methods of NetworkInterface.
  virtual bool SendPacket(rtc::Buffer* packet,
                          rtc::DiffServCodePoint dscp) {
    if (!packet) return false;

    if (media_channel_) {
      media_channel_->OnPacketReceived(packet, rtc::PacketTime());
    }
    if (dump_writer_.get() &&
        rtc::SR_SUCCESS !=
            dump_writer_->WriteRtpPacket(packet->data(), packet->size())) {
      return false;
    }

    ++num_sent_packets_;
    return true;
  }

  virtual bool SendRtcp(rtc::Buffer* packet,
                        rtc::DiffServCodePoint dscp) { return false; }
  virtual int SetOption(MediaChannel::NetworkInterface::SocketType type,
      rtc::Socket::Option opt, int option) {
    return 0;
  }
  virtual void SetDefaultDSCPCode(rtc::DiffServCodePoint dscp) {}

  size_t num_sent_packets() const { return num_sent_packets_; }

 private:
  MediaChannel* media_channel_;
  rtc::scoped_ptr<RtpDumpWriter> dump_writer_;
  size_t num_sent_packets_;

  DISALLOW_COPY_AND_ASSIGN(FileNetworkInterface);
};

class FileMediaEngineTest : public testing::Test {
 public:
  virtual void SetUp() {
    ASSERT_TRUE(GetTempFilename(&voice_input_filename_));
    ASSERT_TRUE(GetTempFilename(&voice_output_filename_));
    ASSERT_TRUE(GetTempFilename(&video_input_filename_));
    ASSERT_TRUE(GetTempFilename(&video_output_filename_));
  }
  virtual void TearDown() {
    // Force to close the dump files, if opened.
    voice_channel_.reset();
    video_channel_.reset();

    DeleteTempFile(voice_input_filename_);
    DeleteTempFile(voice_output_filename_);
    DeleteTempFile(video_input_filename_);
    DeleteTempFile(video_output_filename_);
  }

 protected:
  void CreateEngineAndChannels(const std::string& voice_in,
                               const std::string& voice_out,
                               const std::string& video_in,
                               const std::string& video_out,
                               size_t ssrc_count) {
    // Force to close the dump files, if opened.
    voice_channel_.reset();
    video_channel_.reset();

    if (!voice_in.empty()) {
      EXPECT_TRUE(WriteTestPacketsToFile(voice_in, ssrc_count));
    }
    if (!video_in.empty()) {
      EXPECT_TRUE(WriteTestPacketsToFile(video_in, ssrc_count));
    }

    engine_.reset(new FileMediaEngine);
    engine_->set_voice_input_filename(voice_in);
    engine_->set_voice_output_filename(voice_out);
    engine_->set_video_input_filename(video_in);
    engine_->set_video_output_filename(video_out);
    engine_->set_rtp_sender_thread(rtc::Thread::Current());

    voice_channel_.reset(engine_->CreateChannel());
    video_channel_.reset(engine_->CreateVideoChannel(VideoOptions(), NULL));
  }

  bool GetTempFilename(std::string* filename) {
    rtc::Pathname temp_path;
    if (!rtc::Filesystem::GetTemporaryFolder(temp_path, true, NULL)) {
      return false;
    }
    temp_path.SetPathname(
        rtc::Filesystem::TempFilename(temp_path, "fme-test-"));

    if (filename) {
      *filename = temp_path.pathname();
    }
    return true;
  }

  bool WriteTestPacketsToFile(const std::string& filename, size_t ssrc_count) {
    rtc::scoped_ptr<rtc::StreamInterface> stream(
        rtc::Filesystem::OpenFile(rtc::Pathname(filename), "wb"));
    bool ret = (NULL != stream.get());
    RtpDumpWriter writer(stream.get());

    for (size_t i = 0; i < ssrc_count; ++i) {
      ret &= RtpTestUtility::WriteTestPackets(
          RtpTestUtility::GetTestPacketCount(), false,
          static_cast<uint32>(RtpTestUtility::kDefaultSsrc + i),
          &writer);
    }
    return ret;
  }

  void DeleteTempFile(std::string filename) {
    rtc::Pathname pathname(filename);
    if (rtc::Filesystem::IsFile(rtc::Pathname(pathname))) {
      rtc::Filesystem::DeleteFile(pathname);
    }
  }

  bool GetSsrcAndPacketCounts(rtc::StreamInterface* stream,
                              size_t* ssrc_count, size_t* packet_count) {
    rtc::scoped_ptr<RtpDumpReader> reader(new RtpDumpReader(stream));
    size_t count = 0;
    RtpDumpPacket packet;
    std::set<uint32> ssrcs;
    while (rtc::SR_SUCCESS == reader->ReadPacket(&packet)) {
      count++;
      uint32 ssrc;
      if (!packet.GetRtpSsrc(&ssrc)) {
        return false;
      }
      ssrcs.insert(ssrc);
    }
    if (ssrc_count) {
      *ssrc_count = ssrcs.size();
    }
    if (packet_count) {
      *packet_count = count;
    }
    return true;
  }

  static const uint32 kWaitTimeout = 3000;
  std::string voice_input_filename_;
  std::string voice_output_filename_;
  std::string video_input_filename_;
  std::string video_output_filename_;
  rtc::scoped_ptr<FileMediaEngine> engine_;
  rtc::scoped_ptr<VoiceMediaChannel> voice_channel_;
  rtc::scoped_ptr<VideoMediaChannel> video_channel_;
};

TEST_F(FileMediaEngineTest, TestDefaultImplementation) {
  CreateEngineAndChannels("", "", "", "", 1);
  EXPECT_TRUE(engine_->Init(rtc::Thread::Current()));
  EXPECT_EQ(0, engine_->GetCapabilities());
  EXPECT_TRUE(NULL == voice_channel_.get());
  EXPECT_TRUE(NULL == video_channel_.get());
  cricket::AudioOptions audio_options;
  EXPECT_TRUE(engine_->SetAudioOptions(audio_options));
  VideoEncoderConfig video_encoder_config;
  EXPECT_TRUE(engine_->SetDefaultVideoEncoderConfig(video_encoder_config));
  EXPECT_TRUE(engine_->SetSoundDevices(NULL, NULL));
  EXPECT_TRUE(engine_->SetVideoCaptureDevice(NULL));
  EXPECT_TRUE(engine_->SetOutputVolume(0));
  EXPECT_EQ(0, engine_->GetInputLevel());
  EXPECT_TRUE(engine_->SetLocalMonitor(true));
  EXPECT_TRUE(engine_->SetVideoCapture(true));
  EXPECT_EQ(0U, engine_->audio_codecs().size());
  EXPECT_EQ(0U, engine_->video_codecs().size());
  AudioCodec voice_codec;
  EXPECT_TRUE(engine_->FindAudioCodec(voice_codec));
  VideoCodec video_codec;
  EXPECT_TRUE(engine_->FindVideoCodec(video_codec));
  engine_->Terminate();
}

// Test that when file path is not pointing to a valid stream file, the channel
// creation function should fail and return NULL.
TEST_F(FileMediaEngineTest, TestBadFilePath) {
  engine_.reset(new FileMediaEngine);
  engine_->set_voice_input_filename(kFakeFileName);
  engine_->set_video_input_filename(kFakeFileName);
  EXPECT_TRUE(engine_->CreateChannel() == NULL);
  EXPECT_TRUE(engine_->CreateVideoChannel(VideoOptions(), NULL) == NULL);
}

TEST_F(FileMediaEngineTest, TestCodecs) {
  CreateEngineAndChannels("", "", "", "", 1);
  std::vector<AudioCodec> voice_codecs = engine_->audio_codecs();
  std::vector<VideoCodec> video_codecs = engine_->video_codecs();
  EXPECT_EQ(0U, voice_codecs.size());
  EXPECT_EQ(0U, video_codecs.size());

  AudioCodec voice_codec(103, "ISAC", 16000, 0, 1, 0);
  voice_codecs.push_back(voice_codec);
  engine_->set_voice_codecs(voice_codecs);
  voice_codecs = engine_->audio_codecs();
  ASSERT_EQ(1U, voice_codecs.size());
  EXPECT_EQ(voice_codec, voice_codecs[0]);

  VideoCodec video_codec(96, "H264-SVC", 320, 240, 30, 0);
  video_codecs.push_back(video_codec);
  engine_->set_video_codecs(video_codecs);
  video_codecs = engine_->video_codecs();
  ASSERT_EQ(1U, video_codecs.size());
  EXPECT_EQ(video_codec, video_codecs[0]);
}

// Test that the capabilities and channel creation of the Filemedia engine
// depend on the stream parameters passed to its constructor.
TEST_F(FileMediaEngineTest, TestGetCapabilities) {
  CreateEngineAndChannels(voice_input_filename_, "", "", "", 1);
  EXPECT_EQ(AUDIO_SEND, engine_->GetCapabilities());
  EXPECT_TRUE(NULL != voice_channel_.get());
  EXPECT_TRUE(NULL == video_channel_.get());

  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
                          1);
  EXPECT_EQ(AUDIO_SEND | AUDIO_RECV, engine_->GetCapabilities());
  EXPECT_TRUE(NULL != voice_channel_.get());
  EXPECT_TRUE(NULL == video_channel_.get());

  CreateEngineAndChannels("", "", video_input_filename_, "", 1);
  EXPECT_EQ(VIDEO_SEND, engine_->GetCapabilities());
  EXPECT_TRUE(NULL == voice_channel_.get());
  EXPECT_TRUE(NULL != video_channel_.get());

  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_,
                          video_input_filename_, video_output_filename_, 1);
  EXPECT_EQ(AUDIO_SEND | AUDIO_RECV | VIDEO_SEND | VIDEO_RECV,
            engine_->GetCapabilities());
  EXPECT_TRUE(NULL != voice_channel_.get());
  EXPECT_TRUE(NULL != video_channel_.get());
}

// FileVideoChannel is the same as FileVoiceChannel in terms of receiving and
// sending the RTP packets. We therefore test only FileVoiceChannel.

// Test that SetSend() controls whether a voice channel sends RTP packets.
TEST_F(FileMediaEngineTest, TestVoiceChannelSetSend) {
  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
                          1);
  EXPECT_TRUE(NULL != voice_channel_.get());
  rtc::MemoryStream net_dump;
  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
  voice_channel_->SetInterface(&net_interface);

  // The channel is not sending yet.
  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
  EXPECT_EQ(0U, net_interface.num_sent_packets());

  // The channel starts sending.
  voice_channel_->SetSend(SEND_MICROPHONE);
  EXPECT_TRUE_WAIT(net_interface.num_sent_packets() >= 1U, kWaitTimeout);

  // The channel stops sending.
  voice_channel_->SetSend(SEND_NOTHING);
  // Wait until packets are all delivered.
  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
  size_t old_number = net_interface.num_sent_packets();
  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
  EXPECT_EQ(old_number, net_interface.num_sent_packets());

  // The channel starts sending again.
  voice_channel_->SetSend(SEND_MICROPHONE);
  EXPECT_TRUE_WAIT(net_interface.num_sent_packets() > old_number, kWaitTimeout);

  // When the function exits, the net_interface object is released. The sender
  // thread may call net_interface to send packets, which results in a segment
  // fault. We hence stop sending and wait until all packets are delivered
  // before we exit this function.
  voice_channel_->SetSend(SEND_NOTHING);
  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
}

// Test the sender thread of the channel. The sender sends RTP packets
// continuously with proper sequence number, timestamp, and payload.
TEST_F(FileMediaEngineTest, TestVoiceChannelSenderThread) {
  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
                          1);
  EXPECT_TRUE(NULL != voice_channel_.get());
  rtc::MemoryStream net_dump;
  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
  voice_channel_->SetInterface(&net_interface);

  voice_channel_->SetSend(SEND_MICROPHONE);
  // Wait until the number of sent packets is no less than 2 * kPacketNumber.
  EXPECT_TRUE_WAIT(
      net_interface.num_sent_packets() >=
          2 * RtpTestUtility::GetTestPacketCount(),
      kWaitTimeout);
  voice_channel_->SetSend(SEND_NOTHING);
  // Wait until packets are all delivered.
  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
      2 * RtpTestUtility::GetTestPacketCount(), &net_dump,
      RtpTestUtility::kDefaultSsrc));

  // Each sent packet is dumped to net_dump and is also feed to the channel
  // via OnPacketReceived, which in turn writes the packets into voice_output_.
  // We next verify the packets in voice_output_.
  voice_channel_.reset();  // Force to close the files.
  rtc::scoped_ptr<rtc::StreamInterface> voice_output_;
  voice_output_.reset(rtc::Filesystem::OpenFile(
      rtc::Pathname(voice_output_filename_), "rb"));
  EXPECT_TRUE(voice_output_.get() != NULL);
  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
      2 * RtpTestUtility::GetTestPacketCount(), voice_output_.get(),
      RtpTestUtility::kDefaultSsrc));
}

// Test that we can specify the ssrc for outgoing RTP packets.
TEST_F(FileMediaEngineTest, TestVoiceChannelSendSsrc) {
  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
                          1);
  EXPECT_TRUE(NULL != voice_channel_.get());
  const uint32 send_ssrc = RtpTestUtility::kDefaultSsrc + 1;
  voice_channel_->AddSendStream(StreamParams::CreateLegacy(send_ssrc));

  rtc::MemoryStream net_dump;
  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
  voice_channel_->SetInterface(&net_interface);

  voice_channel_->SetSend(SEND_MICROPHONE);
  // Wait until the number of sent packets is no less than 2 * kPacketNumber.
  EXPECT_TRUE_WAIT(
      net_interface.num_sent_packets() >=
          2 * RtpTestUtility::GetTestPacketCount(),
      kWaitTimeout);
  voice_channel_->SetSend(SEND_NOTHING);
  // Wait until packets are all delivered.
  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
      2 * RtpTestUtility::GetTestPacketCount(), &net_dump, send_ssrc));

  // Each sent packet is dumped to net_dump and is also feed to the channel
  // via OnPacketReceived, which in turn writes the packets into voice_output_.
  // We next verify the packets in voice_output_.
  voice_channel_.reset();  // Force to close the files.
  rtc::scoped_ptr<rtc::StreamInterface> voice_output_;
  voice_output_.reset(rtc::Filesystem::OpenFile(
      rtc::Pathname(voice_output_filename_), "rb"));
  EXPECT_TRUE(voice_output_.get() != NULL);
  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
      2 * RtpTestUtility::GetTestPacketCount(), voice_output_.get(),
      send_ssrc));
}

// Test the sender thread of the channel, where the input rtpdump has two SSRCs.
TEST_F(FileMediaEngineTest, TestVoiceChannelSenderThreadTwoSsrcs) {
  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
                          2);
  // Verify that voice_input_filename_ contains 2 *
  // RtpTestUtility::GetTestPacketCount() packets
  // with different SSRCs.
  rtc::scoped_ptr<rtc::StreamInterface> input_stream(
      rtc::Filesystem::OpenFile(
          rtc::Pathname(voice_input_filename_), "rb"));
  ASSERT_TRUE(NULL != input_stream.get());
  size_t ssrc_count;
  size_t packet_count;
  EXPECT_TRUE(GetSsrcAndPacketCounts(input_stream.get(), &ssrc_count,
                                     &packet_count));
  EXPECT_EQ(2U, ssrc_count);
  EXPECT_EQ(2 * RtpTestUtility::GetTestPacketCount(), packet_count);
  input_stream.reset();

  // Send 2 * RtpTestUtility::GetTestPacketCount() packets and verify that all
  // these packets have the same SSRCs (that is, the packets with different
  // SSRCs are skipped by the filemediaengine).
  EXPECT_TRUE(NULL != voice_channel_.get());
  rtc::MemoryStream net_dump;
  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
  voice_channel_->SetInterface(&net_interface);
  voice_channel_->SetSend(SEND_MICROPHONE);
  EXPECT_TRUE_WAIT(
      net_interface.num_sent_packets() >=
          2 * RtpTestUtility::GetTestPacketCount(),
      kWaitTimeout);
  voice_channel_->SetSend(SEND_NOTHING);
  // Wait until packets are all delivered.
  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
  net_dump.Rewind();
  EXPECT_TRUE(GetSsrcAndPacketCounts(&net_dump, &ssrc_count, &packet_count));
  EXPECT_EQ(1U, ssrc_count);
  EXPECT_GE(packet_count, 2 * RtpTestUtility::GetTestPacketCount());
}

// Test SendIntraFrame() and RequestIntraFrame() of video channel.
TEST_F(FileMediaEngineTest, TestVideoChannelIntraFrame) {
  CreateEngineAndChannels("", "", video_input_filename_, video_output_filename_,
                          1);
  EXPECT_TRUE(NULL != video_channel_.get());
  EXPECT_FALSE(video_channel_->SendIntraFrame());
  EXPECT_FALSE(video_channel_->RequestIntraFrame());
}

}  // namespace cricket
