/*
 * libjingle
 * Copyright 2004--2011, 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/base/buffer.h"
#include "talk/base/gunit.h"
#include "talk/base/helpers.h"
#include "talk/base/pathutils.h"
#include "talk/base/stream.h"
#include "talk/session/phone/filemediaengine.h"
#include "talk/session/phone/rtpdump.h"
#include "talk/session/phone/testutils.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(talk_base::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(talk_base::Buffer* packet) {
    if (!packet) return false;

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

    ++num_sent_packets_;
    return true;
  }

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

  size_t num_sent_packets() const { return num_sent_packets_; }

 private:
  MediaChannel* media_channel_;
  talk_base::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);

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

    return ret;
  }

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

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

  bool WriteTestPacketsToFile(const std::string& filename, size_t ssrc_count) {
    talk_base::scoped_ptr<talk_base::StreamInterface> stream(
        talk_base::Filesystem::OpenFile(talk_base::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,
          RtpTestUtility::kDefaultSsrc + i, &writer);
    }
    return ret;
  }

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

  bool GetSsrcAndPacketCounts(talk_base::StreamInterface* stream,
                              size_t* ssrc_count, size_t* packet_count) {
    talk_base::scoped_ptr<RtpDumpReader> reader(new RtpDumpReader(stream));
    size_t count = 0;
    RtpDumpPacket packet;
    std::set<uint32> ssrcs;
    while (talk_base::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_;
  talk_base::scoped_ptr<FileMediaEngine> engine_;
  talk_base::scoped_ptr<VoiceMediaChannel> voice_channel_;
  talk_base::scoped_ptr<VideoMediaChannel> video_channel_;
};

TEST_F(FileMediaEngineTest, TestDefaultImplementation) {
  EXPECT_TRUE(CreateEngineAndChannels("", "", "", "", 1));
  EXPECT_TRUE(engine_->Init());
  EXPECT_EQ(0, engine_->GetCapabilities());
  EXPECT_TRUE(NULL == voice_channel_.get());
  EXPECT_TRUE(NULL == video_channel_.get());
  EXPECT_TRUE(NULL == engine_->CreateSoundclip());
  EXPECT_TRUE(engine_->SetAudioOptions(0));
  EXPECT_TRUE(engine_->SetVideoOptions(0));
  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_->SetLocalRenderer(NULL));
  EXPECT_EQ(CR_SUCCESS, 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());
  talk_base::MemoryStream net_dump;
  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
  voice_channel_->SetInterface(&net_interface);

  // The channel is not sending yet.
  talk_base::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.
  talk_base::Thread::Current()->ProcessMessages(kWaitTimeMs);
  size_t old_number = net_interface.num_sent_packets();
  talk_base::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);
  talk_base::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());
  talk_base::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.
  talk_base::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.
  talk_base::scoped_ptr<talk_base::StreamInterface> voice_output_;
  voice_output_.reset(talk_base::Filesystem::OpenFile(
      talk_base::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_->SetSendSsrc(send_ssrc);

  talk_base::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.
  talk_base::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.
  talk_base::scoped_ptr<talk_base::StreamInterface> voice_output_;
  voice_output_.reset(talk_base::Filesystem::OpenFile(
      talk_base::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.
  talk_base::scoped_ptr<talk_base::StreamInterface> input_stream(
      talk_base::Filesystem::OpenFile(
          talk_base::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());
  talk_base::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.
  talk_base::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
