/*
 * 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->length())) {
      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() {
    setup_ok_ = true;
    setup_ok_ &= GetTempFilename(&voice_input_filename_);
    setup_ok_ &= GetTempFilename(&voice_output_filename_);
    setup_ok_ &= GetTempFilename(&video_input_filename_);
    setup_ok_ &= 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:
  bool 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();

    bool ret = setup_ok_;
    if (!voice_in.empty()) {
      ret &= WriteTestPacketsToFile(voice_in, ssrc_count);
    }
    if (!video_in.empty()) {
      ret &= 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(NULL));

    return ret;
  }

  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;
  bool setup_ok_;
  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) {
  EXPECT_TRUE(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());
  EXPECT_TRUE(NULL == engine_->CreateSoundclip());
  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(NULL) == NULL);
}

TEST_F(FileMediaEngineTest, TestCodecs) {
  EXPECT_TRUE(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) {
  EXPECT_TRUE(CreateEngineAndChannels(voice_input_filename_, "", "", "", 1));
  EXPECT_EQ(AUDIO_SEND, engine_->GetCapabilities());
  EXPECT_TRUE(NULL != voice_channel_.get());
  EXPECT_TRUE(NULL == video_channel_.get());

  EXPECT_TRUE(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());

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

  EXPECT_TRUE(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) {
  EXPECT_TRUE(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) {
  EXPECT_TRUE(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) {
  EXPECT_TRUE(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) {
  EXPECT_TRUE(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) {
  EXPECT_TRUE(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
