// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/big_endian.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "chrome/browser/media/webrtc_rtp_dump_writer.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/zlib/zlib.h"

static const size_t kMinimumRtpHeaderLength = 12;

static void CreateFakeRtpPacketHeader(size_t csrc_count,
                                      size_t extension_header_count,
                                      std::vector<uint8>* packet_header) {
  packet_header->resize(kMinimumRtpHeaderLength + csrc_count * sizeof(uint32) +
                        (extension_header_count + 1) * sizeof(uint32));

  memset(&(*packet_header)[0], 0, packet_header->size());

  // First byte format: vvpxcccc, where 'vv' is the version, 'p' is padding, 'x'
  // is the extension bit, 'cccc' is the CSRC count.
  (*packet_header)[0] = 0;
  (*packet_header)[0] |= (0x2 << 6);  // version.
  // The extension bit.
  (*packet_header)[0] |= (extension_header_count > 0 ? (0x1 << 4) : 0);
  (*packet_header)[0] |= (csrc_count & 0xf);

  // Set extension length.
  size_t offset = kMinimumRtpHeaderLength +
                  (csrc_count & 0xf) * sizeof(uint32) + sizeof(uint16);
  base::WriteBigEndian(reinterpret_cast<char*>(&(*packet_header)[offset]),
                       static_cast<uint16>(extension_header_count));
}

class WebRtcRtpDumpWriterTest : public testing::Test {
 public:
  WebRtcRtpDumpWriterTest()
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP |
                       content::TestBrowserThreadBundle::REAL_FILE_THREAD),
        temp_dir_(new base::ScopedTempDir()) {}

  virtual void SetUp() {
    ASSERT_TRUE(temp_dir_->CreateUniqueTempDir());

    incoming_dump_path_ = temp_dir_->path().AppendASCII("rtpdump_recv");
    outgoing_dump_path_ = temp_dir_->path().AppendASCII("rtpdump_send");
    writer_.reset(new WebRtcRtpDumpWriter(
        incoming_dump_path_,
        outgoing_dump_path_,
        4 * 1024 * 1024,
        base::Bind(&WebRtcRtpDumpWriterTest::OnMaxSizeReached,
                   base::Unretained(this))));
  }

  // Verifies that the dump contains records of |rtp_packet| repeated
  // |packet_count| times.
  void VerifyDumps(size_t incoming_packet_count, size_t outgoing_packet_count) {
    std::string incoming_dump;
    std::string outgoing_dump;

    if (incoming_packet_count) {
      EXPECT_TRUE(base::ReadFileToString(incoming_dump_path_, &incoming_dump));
      EXPECT_TRUE(VerifyCompressedDump(&incoming_dump, incoming_packet_count));
    } else {
      EXPECT_FALSE(base::PathExists(incoming_dump_path_));
    }

    if (outgoing_packet_count) {
      EXPECT_TRUE(base::ReadFileToString(outgoing_dump_path_, &outgoing_dump));
      EXPECT_TRUE(VerifyCompressedDump(&outgoing_dump, outgoing_packet_count));
    } else {
      EXPECT_FALSE(base::PathExists(outgoing_dump_path_));
    }
  }

  MOCK_METHOD2(OnEndDumpDone, void(bool, bool));
  MOCK_METHOD0(OnMaxSizeReached, void(void));

 protected:
  // Verifies the compressed dump file contains the expected number of packets.
  bool VerifyCompressedDump(std::string* dump, size_t expected_packet_count) {
    EXPECT_GT(dump->size(), 0U);

    std::vector<uint8> decompressed_dump;
    EXPECT_TRUE(Decompress(dump, &decompressed_dump));

    size_t actual_packet_count = 0;
    EXPECT_TRUE(ReadDecompressedDump(decompressed_dump, &actual_packet_count));
    EXPECT_EQ(expected_packet_count, actual_packet_count);

    return true;
  }

  // Decompresses the |input| into |output|.
  bool Decompress(std::string* input, std::vector<uint8>* output) {
    z_stream stream = {0};

    int result = inflateInit2(&stream, 15 + 16);
    EXPECT_EQ(Z_OK, result);

    output->resize(input->size() * 100);

    stream.next_in =
        reinterpret_cast<unsigned char*>(const_cast<char*>(&(*input)[0]));
    stream.avail_in = input->size();
    stream.next_out = &(*output)[0];
    stream.avail_out = output->size();

    result = inflate(&stream, Z_FINISH);
    DCHECK_EQ(Z_STREAM_END, result);
    result = inflateEnd(&stream);
    DCHECK_EQ(Z_OK, result);

    output->resize(output->size() - stream.avail_out);
    return true;
  }

  // Tries to read |dump| as a rtpplay dump file and returns the number of
  // packets found in the dump.
  bool ReadDecompressedDump(const std::vector<uint8>& dump,
                            size_t* packet_count) {
    static const char kFirstLine[] = "#!rtpplay1.0 0.0.0.0/0\n";
    static const size_t kDumpFileHeaderSize = 4 * sizeof(uint32);

    *packet_count = 0;
    size_t dump_pos = 0;

    // Verifies the first line.
    EXPECT_EQ(memcmp(&dump[0], kFirstLine, arraysize(kFirstLine) - 1), 0);

    dump_pos += arraysize(kFirstLine) - 1;
    EXPECT_GT(dump.size(), dump_pos);

    // Skips the file header.
    dump_pos += kDumpFileHeaderSize;
    EXPECT_GT(dump.size(), dump_pos);

    // Reads each packet dump.
    while (dump_pos < dump.size()) {
      size_t packet_dump_length = 0;
      if (!VerifyPacketDump(&dump[dump_pos],
                            dump.size() - dump_pos,
                            &packet_dump_length)) {
        DVLOG(0) << "Failed to read the packet dump for packet "
                 << *packet_count << ", dump_pos = " << dump_pos
                 << ", dump_length = " << dump.size();
        return false;
      }

      EXPECT_GE(dump.size(), dump_pos + packet_dump_length);
      dump_pos += packet_dump_length;

      (*packet_count)++;
    }
    return true;
  }

  // Tries to read one packet dump starting at |dump| and returns the size of
  // the packet dump.
  bool VerifyPacketDump(const uint8* dump,
                        size_t dump_length,
                        size_t* packet_dump_length) {
    static const size_t kDumpHeaderLength = 8;

    size_t dump_pos = 0;
    base::ReadBigEndian(reinterpret_cast<const char*>(dump + dump_pos),
                        reinterpret_cast<uint16*>(packet_dump_length));
    if (*packet_dump_length < kDumpHeaderLength + kMinimumRtpHeaderLength)
      return false;

    EXPECT_GE(dump_length, *packet_dump_length);
    dump_pos += sizeof(uint16);

    uint16 rtp_packet_length = 0;
    base::ReadBigEndian(reinterpret_cast<const char*>(dump + dump_pos),
                        &rtp_packet_length);
    if (rtp_packet_length < kMinimumRtpHeaderLength)
      return false;

    dump_pos += sizeof(uint16);

    // Skips the elapsed time field.
    dump_pos += sizeof(uint32);

    return IsValidRtpHeader(dump + dump_pos,
                            *packet_dump_length - kDumpHeaderLength);
  }

  // Returns true if |header| is a valid RTP header.
  bool IsValidRtpHeader(const uint8* header, size_t length) {
    if ((header[0] & 0xC0) != 0x80)
      return false;

    size_t cc_count = header[0] & 0x0F;
    size_t header_length_without_extn = kMinimumRtpHeaderLength + 4 * cc_count;

    if (length < header_length_without_extn)
      return false;

    uint16 extension_count = 0;
    base::ReadBigEndian(
        reinterpret_cast<const char*>(header + header_length_without_extn + 2),
        &extension_count);

    if (length < (extension_count + 1) * 4 + header_length_without_extn)
      return false;

    return true;
  }

  content::TestBrowserThreadBundle thread_bundle_;
  scoped_ptr<base::ScopedTempDir> temp_dir_;
  base::FilePath incoming_dump_path_;
  base::FilePath outgoing_dump_path_;
  scoped_ptr<WebRtcRtpDumpWriter> writer_;
};

TEST_F(WebRtcRtpDumpWriterTest, NoDumpFileIfNoPacketDumped) {
  // The scope is used to make sure the EXPECT_CALL is checked before exiting
  // the scope.
  {
    EXPECT_CALL(*this, OnEndDumpDone(false, false));

    writer_->EndDump(RTP_DUMP_BOTH,
                     base::Bind(&WebRtcRtpDumpWriterTest::OnEndDumpDone,
                                base::Unretained(this)));

    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    base::RunLoop().RunUntilIdle();
    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    base::RunLoop().RunUntilIdle();
  }
  EXPECT_FALSE(base::PathExists(incoming_dump_path_));
  EXPECT_FALSE(base::PathExists(outgoing_dump_path_));
}

TEST_F(WebRtcRtpDumpWriterTest, WriteAndFlushSmallSizeDump) {
  std::vector<uint8> packet_header;
  CreateFakeRtpPacketHeader(1, 2, &packet_header);

  writer_->WriteRtpPacket(
      &packet_header[0], packet_header.size(), 100, true);
  writer_->WriteRtpPacket(
      &packet_header[0], packet_header.size(), 100, false);

  // The scope is used to make sure the EXPECT_CALL is checked before exiting
  // the scope.
  {
    EXPECT_CALL(*this, OnEndDumpDone(true, true));

    writer_->EndDump(RTP_DUMP_BOTH,
                     base::Bind(&WebRtcRtpDumpWriterTest::OnEndDumpDone,
                                base::Unretained(this)));

    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    base::RunLoop().RunUntilIdle();
    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    base::RunLoop().RunUntilIdle();
  }

  VerifyDumps(1, 1);
}

TEST_F(WebRtcRtpDumpWriterTest, WriteOverMaxLimit) {
  // Reset the writer with a small max size limit.
  writer_.reset(new WebRtcRtpDumpWriter(
      incoming_dump_path_,
      outgoing_dump_path_,
      100,
      base::Bind(&WebRtcRtpDumpWriterTest::OnMaxSizeReached,
                 base::Unretained(this))));

  std::vector<uint8> packet_header;
  CreateFakeRtpPacketHeader(3, 4, &packet_header);

  const size_t kPacketCount = 200;
  // The scope is used to make sure the EXPECT_CALL is checked before exiting
  // the scope.
  {
    EXPECT_CALL(*this, OnMaxSizeReached()).Times(testing::AtLeast(1));

    // Write enough packets to overflow the in-memory buffer and max limit.
    for (size_t i = 0; i < kPacketCount; ++i) {
      writer_->WriteRtpPacket(
          &packet_header[0], packet_header.size(), 100, true);

      writer_->WriteRtpPacket(
          &packet_header[0], packet_header.size(), 100, false);
    }

    EXPECT_CALL(*this, OnEndDumpDone(true, true));

    writer_->EndDump(RTP_DUMP_BOTH,
                     base::Bind(&WebRtcRtpDumpWriterTest::OnEndDumpDone,
                                base::Unretained(this)));

    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    base::RunLoop().RunUntilIdle();
    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    base::RunLoop().RunUntilIdle();
  }
  VerifyDumps(kPacketCount, kPacketCount);
}

TEST_F(WebRtcRtpDumpWriterTest, DestroyWriterBeforeEndDumpCallback) {
  EXPECT_CALL(*this, OnEndDumpDone(testing::_, testing::_)).Times(0);

  writer_->EndDump(RTP_DUMP_BOTH,
                   base::Bind(&WebRtcRtpDumpWriterTest::OnEndDumpDone,
                              base::Unretained(this)));

  writer_.reset();

  content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
  base::RunLoop().RunUntilIdle();
  content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
  base::RunLoop().RunUntilIdle();
}

TEST_F(WebRtcRtpDumpWriterTest, EndDumpsSeparately) {
  std::vector<uint8> packet_header;
  CreateFakeRtpPacketHeader(1, 2, &packet_header);

  writer_->WriteRtpPacket(
      &packet_header[0], packet_header.size(), 100, true);
  writer_->WriteRtpPacket(
      &packet_header[0], packet_header.size(), 100, true);
  writer_->WriteRtpPacket(
      &packet_header[0], packet_header.size(), 100, false);

  // The scope is used to make sure the EXPECT_CALL is checked before exiting
  // the scope.
  {
    EXPECT_CALL(*this, OnEndDumpDone(true, false));
    EXPECT_CALL(*this, OnEndDumpDone(false, true));

    writer_->EndDump(RTP_DUMP_INCOMING,
                     base::Bind(&WebRtcRtpDumpWriterTest::OnEndDumpDone,
                                base::Unretained(this)));

    writer_->EndDump(RTP_DUMP_OUTGOING,
                     base::Bind(&WebRtcRtpDumpWriterTest::OnEndDumpDone,
                                base::Unretained(this)));

    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    base::RunLoop().RunUntilIdle();
    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    base::RunLoop().RunUntilIdle();
  }

  VerifyDumps(2, 1);
}
