// libjingle
// Copyright 2010 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 <string>

#include "talk/media/base/fakemediaengine.h"
#include "talk/media/base/rtpdump.h"
#include "talk/media/base/testutils.h"
#include "talk/p2p/base/fakesession.h"
#include "talk/session/media/channel.h"
#include "talk/session/media/mediarecorder.h"
#include "webrtc/base/bytebuffer.h"
#include "webrtc/base/fileutils.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/thread.h"

namespace cricket {

rtc::StreamInterface* Open(const std::string& path) {
  return rtc::Filesystem::OpenFile(
      rtc::Pathname(path), "wb");
}

/////////////////////////////////////////////////////////////////////////
// Test RtpDumpSink
/////////////////////////////////////////////////////////////////////////
class RtpDumpSinkTest : public testing::Test {
 public:
  virtual void SetUp() {
    EXPECT_TRUE(rtc::Filesystem::GetTemporaryFolder(path_, true, NULL));
    path_.SetFilename("sink-test.rtpdump");
    sink_.reset(new RtpDumpSink(Open(path_.pathname())));

    for (int i = 0; i < ARRAY_SIZE(rtp_buf_); ++i) {
      RtpTestUtility::kTestRawRtpPackets[i].WriteToByteBuffer(
          RtpTestUtility::kDefaultSsrc, &rtp_buf_[i]);
    }
  }

  virtual void TearDown() {
    stream_.reset();
    EXPECT_TRUE(rtc::Filesystem::DeleteFile(path_));
  }

 protected:
  void OnRtpPacket(const RawRtpPacket& raw) {
    rtc::ByteBuffer buf;
    raw.WriteToByteBuffer(RtpTestUtility::kDefaultSsrc, &buf);
    sink_->OnPacket(buf.Data(), buf.Length(), false);
  }

  rtc::StreamResult ReadPacket(RtpDumpPacket* packet) {
    if (!stream_.get()) {
      sink_.reset();  // This will close the file. So we can read it.
      stream_.reset(rtc::Filesystem::OpenFile(path_, "rb"));
      reader_.reset(new RtpDumpReader(stream_.get()));
    }
    return reader_->ReadPacket(packet);
  }

  rtc::Pathname path_;
  rtc::scoped_ptr<RtpDumpSink> sink_;
  rtc::ByteBuffer rtp_buf_[3];
  rtc::scoped_ptr<rtc::StreamInterface> stream_;
  rtc::scoped_ptr<RtpDumpReader> reader_;
};

TEST_F(RtpDumpSinkTest, TestRtpDumpSink) {
  // By default, the sink is disabled. The 1st packet is not written.
  EXPECT_FALSE(sink_->IsEnabled());
  sink_->set_packet_filter(PF_ALL);
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[0]);

  // Enable the sink. The 2nd packet is written.
  EXPECT_TRUE(sink_->Enable(true));
  EXPECT_TRUE(sink_->IsEnabled());
  EXPECT_TRUE(rtc::Filesystem::IsFile(path_.pathname()));
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[1]);

  // Disable the sink. The 3rd packet is not written.
  EXPECT_TRUE(sink_->Enable(false));
  EXPECT_FALSE(sink_->IsEnabled());
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[2]);

  // Read the recorded file and verify it contains only the 2nd packet.
  RtpDumpPacket packet;
  EXPECT_EQ(rtc::SR_SUCCESS, ReadPacket(&packet));
  EXPECT_TRUE(RtpTestUtility::VerifyPacket(
      &packet, &RtpTestUtility::kTestRawRtpPackets[1], false));
  EXPECT_EQ(rtc::SR_EOS, ReadPacket(&packet));
}

TEST_F(RtpDumpSinkTest, TestRtpDumpSinkMaxSize) {
  EXPECT_TRUE(sink_->Enable(true));
  sink_->set_packet_filter(PF_ALL);
  sink_->SetMaxSize(strlen(RtpDumpFileHeader::kFirstLine) +
                    RtpDumpFileHeader::kHeaderLength +
                    RtpDumpPacket::kHeaderLength +
                    RtpTestUtility::kTestRawRtpPackets[0].size());
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[0]);

  // Exceed the limit size: the 2nd and 3rd packets are not written.
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[1]);
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[2]);

  // Read the recorded file and verify that it contains only the first packet.
  RtpDumpPacket packet;
  EXPECT_EQ(rtc::SR_SUCCESS, ReadPacket(&packet));
  EXPECT_TRUE(RtpTestUtility::VerifyPacket(
      &packet, &RtpTestUtility::kTestRawRtpPackets[0], false));
  EXPECT_EQ(rtc::SR_EOS, ReadPacket(&packet));
}

TEST_F(RtpDumpSinkTest, TestRtpDumpSinkFilter) {
  // The default filter is PF_NONE.
  EXPECT_EQ(PF_NONE, sink_->packet_filter());

  // Set to PF_RTPHEADER before enable.
  sink_->set_packet_filter(PF_RTPHEADER);
  EXPECT_EQ(PF_RTPHEADER, sink_->packet_filter());
  EXPECT_TRUE(sink_->Enable(true));
  // We dump only the header of the first packet.
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[0]);

  // Set the filter to PF_RTPPACKET. We dump all the second packet.
  sink_->set_packet_filter(PF_RTPPACKET);
  EXPECT_EQ(PF_RTPPACKET, sink_->packet_filter());
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[1]);

  // Set the filter to PF_NONE. We do not dump the third packet.
  sink_->set_packet_filter(PF_NONE);
  EXPECT_EQ(PF_NONE, sink_->packet_filter());
  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[2]);

  // Read the recorded file and verify the header of the first packet and
  // the whole packet for the second packet.
  RtpDumpPacket packet;
  EXPECT_EQ(rtc::SR_SUCCESS, ReadPacket(&packet));
  EXPECT_TRUE(RtpTestUtility::VerifyPacket(
      &packet, &RtpTestUtility::kTestRawRtpPackets[0], true));
  EXPECT_EQ(rtc::SR_SUCCESS, ReadPacket(&packet));
  EXPECT_TRUE(RtpTestUtility::VerifyPacket(
      &packet, &RtpTestUtility::kTestRawRtpPackets[1], false));
  EXPECT_EQ(rtc::SR_EOS, ReadPacket(&packet));
}

/////////////////////////////////////////////////////////////////////////
// Test MediaRecorder
/////////////////////////////////////////////////////////////////////////
void TestMediaRecorder(BaseChannel* channel,
                       FakeVideoMediaChannel* video_media_channel,
                       int filter) {
  // Create media recorder.
  rtc::scoped_ptr<MediaRecorder> recorder(new MediaRecorder);
  // Fail to EnableChannel before AddChannel.
  EXPECT_FALSE(recorder->EnableChannel(channel, true, true, SINK_PRE_CRYPTO));
  EXPECT_FALSE(channel->HasSendSinks(SINK_PRE_CRYPTO));
  EXPECT_FALSE(channel->HasRecvSinks(SINK_PRE_CRYPTO));
  EXPECT_FALSE(channel->HasSendSinks(SINK_POST_CRYPTO));
  EXPECT_FALSE(channel->HasRecvSinks(SINK_POST_CRYPTO));

  // Add the channel to the recorder.
  rtc::Pathname path;
  EXPECT_TRUE(rtc::Filesystem::GetTemporaryFolder(path, true, NULL));
  path.SetFilename("send.rtpdump");
  std::string send_file = path.pathname();
  path.SetFilename("recv.rtpdump");
  std::string recv_file = path.pathname();
  if (video_media_channel) {
    EXPECT_TRUE(recorder->AddChannel(static_cast<VideoChannel*>(channel),
                                     Open(send_file), Open(recv_file), filter));
  } else {
    EXPECT_TRUE(recorder->AddChannel(static_cast<VoiceChannel*>(channel),
                                     Open(send_file), Open(recv_file), filter));
  }

  // Enable recording only the sent media.
  EXPECT_TRUE(recorder->EnableChannel(channel, true, false, SINK_PRE_CRYPTO));
  EXPECT_TRUE(channel->HasSendSinks(SINK_PRE_CRYPTO));
  EXPECT_FALSE(channel->HasRecvSinks(SINK_POST_CRYPTO));
  EXPECT_FALSE(channel->HasSendSinks(SINK_POST_CRYPTO));
  EXPECT_FALSE(channel->HasRecvSinks(SINK_POST_CRYPTO));
  if (video_media_channel) {
    EXPECT_TRUE_WAIT(video_media_channel->sent_intra_frame(), 100);
  }

  // Enable recording only the received meida.
  EXPECT_TRUE(recorder->EnableChannel(channel, false, true, SINK_PRE_CRYPTO));
  EXPECT_FALSE(channel->HasSendSinks(SINK_PRE_CRYPTO));
  EXPECT_TRUE(channel->HasRecvSinks(SINK_PRE_CRYPTO));
  if (video_media_channel) {
    EXPECT_TRUE(video_media_channel->requested_intra_frame());
  }

  // Enable recording both the sent and the received video.
  EXPECT_TRUE(recorder->EnableChannel(channel, true, true, SINK_PRE_CRYPTO));
  EXPECT_TRUE(channel->HasSendSinks(SINK_PRE_CRYPTO));
  EXPECT_TRUE(channel->HasRecvSinks(SINK_PRE_CRYPTO));

  // Enable recording only headers.
  if (video_media_channel) {
    video_media_channel->set_sent_intra_frame(false);
    video_media_channel->set_requested_intra_frame(false);
  }
  EXPECT_TRUE(recorder->EnableChannel(channel, true, true, SINK_PRE_CRYPTO));
  EXPECT_TRUE(channel->HasSendSinks(SINK_PRE_CRYPTO));
  EXPECT_TRUE(channel->HasRecvSinks(SINK_PRE_CRYPTO));
  if (video_media_channel) {
    if ((filter & PF_RTPPACKET) == PF_RTPPACKET) {
      // If record the whole RTP packet, trigers FIR.
      EXPECT_TRUE(video_media_channel->requested_intra_frame());
      EXPECT_TRUE(video_media_channel->sent_intra_frame());
    } else {
      // If record only the RTP header, does not triger FIR.
      EXPECT_FALSE(video_media_channel->requested_intra_frame());
      EXPECT_FALSE(video_media_channel->sent_intra_frame());
    }
  }

  // Remove the voice channel from the recorder.
  recorder->RemoveChannel(channel, SINK_PRE_CRYPTO);
  EXPECT_FALSE(channel->HasSendSinks(SINK_PRE_CRYPTO));
  EXPECT_FALSE(channel->HasRecvSinks(SINK_PRE_CRYPTO));

  // Delete all files.
  recorder.reset();
  EXPECT_TRUE(rtc::Filesystem::DeleteFile(send_file));
  EXPECT_TRUE(rtc::Filesystem::DeleteFile(recv_file));
}

// Fisrt start recording header and then start recording media. Verify that
// differnt files are created for header and media.
void TestRecordHeaderAndMedia(BaseChannel* channel,
                              FakeVideoMediaChannel* video_media_channel) {
  // Create RTP header recorder.
  rtc::scoped_ptr<MediaRecorder> header_recorder(new MediaRecorder);

  rtc::Pathname path;
  EXPECT_TRUE(rtc::Filesystem::GetTemporaryFolder(path, true, NULL));
  path.SetFilename("send-header.rtpdump");
  std::string send_header_file = path.pathname();
  path.SetFilename("recv-header.rtpdump");
  std::string recv_header_file = path.pathname();
  if (video_media_channel) {
    EXPECT_TRUE(header_recorder->AddChannel(
        static_cast<VideoChannel*>(channel),
        Open(send_header_file), Open(recv_header_file), PF_RTPHEADER));
  } else {
    EXPECT_TRUE(header_recorder->AddChannel(
        static_cast<VoiceChannel*>(channel),
        Open(send_header_file), Open(recv_header_file), PF_RTPHEADER));
  }

  // Enable recording both sent and received.
  EXPECT_TRUE(
      header_recorder->EnableChannel(channel, true, true, SINK_POST_CRYPTO));
  EXPECT_TRUE(channel->HasSendSinks(SINK_POST_CRYPTO));
  EXPECT_TRUE(channel->HasRecvSinks(SINK_POST_CRYPTO));
  EXPECT_FALSE(channel->HasSendSinks(SINK_PRE_CRYPTO));
  EXPECT_FALSE(channel->HasRecvSinks(SINK_PRE_CRYPTO));
  if (video_media_channel) {
    EXPECT_FALSE(video_media_channel->sent_intra_frame());
    EXPECT_FALSE(video_media_channel->requested_intra_frame());
  }

  // Verify that header files are created.
  EXPECT_TRUE(rtc::Filesystem::IsFile(send_header_file));
  EXPECT_TRUE(rtc::Filesystem::IsFile(recv_header_file));

  // Create RTP header recorder.
  rtc::scoped_ptr<MediaRecorder> recorder(new MediaRecorder);
  path.SetFilename("send.rtpdump");
  std::string send_file = path.pathname();
  path.SetFilename("recv.rtpdump");
  std::string recv_file = path.pathname();
  if (video_media_channel) {
    EXPECT_TRUE(recorder->AddChannel(
        static_cast<VideoChannel*>(channel),
        Open(send_file), Open(recv_file), PF_RTPPACKET));
  } else {
    EXPECT_TRUE(recorder->AddChannel(
        static_cast<VoiceChannel*>(channel),
        Open(send_file), Open(recv_file), PF_RTPPACKET));
  }

  // Enable recording both sent and received.
  EXPECT_TRUE(recorder->EnableChannel(channel, true, true, SINK_PRE_CRYPTO));
  EXPECT_TRUE(channel->HasSendSinks(SINK_POST_CRYPTO));
  EXPECT_TRUE(channel->HasRecvSinks(SINK_POST_CRYPTO));
  EXPECT_TRUE(channel->HasSendSinks(SINK_PRE_CRYPTO));
  EXPECT_TRUE(channel->HasRecvSinks(SINK_PRE_CRYPTO));
  if (video_media_channel) {
    EXPECT_TRUE_WAIT(video_media_channel->sent_intra_frame(), 100);
    EXPECT_TRUE(video_media_channel->requested_intra_frame());
  }

  // Verify that media files are created.
  EXPECT_TRUE(rtc::Filesystem::IsFile(send_file));
  EXPECT_TRUE(rtc::Filesystem::IsFile(recv_file));

  // Delete all files.
  header_recorder.reset();
  recorder.reset();
  EXPECT_TRUE(rtc::Filesystem::DeleteFile(send_header_file));
  EXPECT_TRUE(rtc::Filesystem::DeleteFile(recv_header_file));
  EXPECT_TRUE(rtc::Filesystem::DeleteFile(send_file));
  EXPECT_TRUE(rtc::Filesystem::DeleteFile(recv_file));
}

TEST(MediaRecorderTest, TestMediaRecorderVoiceChannel) {
  // Create the voice channel.
  FakeSession session(true);
  FakeMediaEngine media_engine;
  VoiceChannel channel(rtc::Thread::Current(), &media_engine,
                       new FakeVoiceMediaChannel(NULL), &session, "", false);
  EXPECT_TRUE(channel.Init());
  TestMediaRecorder(&channel, NULL, PF_RTPPACKET);
  TestMediaRecorder(&channel, NULL, PF_RTPHEADER);
  TestRecordHeaderAndMedia(&channel, NULL);
}

TEST(MediaRecorderTest, TestMediaRecorderVideoChannel) {
  // Create the video channel.
  FakeSession session(true);
  FakeMediaEngine media_engine;
  FakeVideoMediaChannel* media_channel = new FakeVideoMediaChannel(NULL);
  VideoChannel channel(rtc::Thread::Current(), &media_engine,
                       media_channel, &session, "", false, NULL);
  EXPECT_TRUE(channel.Init());
  TestMediaRecorder(&channel, media_channel, PF_RTPPACKET);
  TestMediaRecorder(&channel, media_channel, PF_RTPHEADER);
  TestRecordHeaderAndMedia(&channel, media_channel);
}

}  // namespace cricket
