/*
 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <memory>

#include "webrtc/rtc_base/arraysize.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/filerotatingstream.h"
#include "webrtc/rtc_base/fileutils.h"
#include "webrtc/rtc_base/gunit.h"
#include "webrtc/rtc_base/pathutils.h"
#include "webrtc/test/testsupport/fileutils.h"

namespace rtc {

namespace {

void CleanupLogDirectory(const FileRotatingStream& stream) {
  for (size_t i = 0; i < stream.GetNumFiles(); ++i) {
    // Ignore return value, not all files are expected to exist.
    webrtc::test::RemoveFile(stream.GetFilePath(i));
  }
}

}  // namespace

#if defined (WEBRTC_ANDROID)
// Fails on Android: https://bugs.chromium.org/p/webrtc/issues/detail?id=4364.
#define MAYBE_FileRotatingStreamTest DISABLED_FileRotatingStreamTest
#else
#define MAYBE_FileRotatingStreamTest FileRotatingStreamTest
#endif

class MAYBE_FileRotatingStreamTest : public ::testing::Test {
 protected:
  static const char* kFilePrefix;
  static const size_t kMaxFileSize;

  void Init(const std::string& dir_name,
            const std::string& file_prefix,
            size_t max_file_size,
            size_t num_log_files) {
    dir_path_ = webrtc::test::OutputPath();

    // Append per-test output path in order to run within gtest parallel.
    dir_path_.append(dir_name);
    dir_path_.push_back(Pathname::DefaultFolderDelimiter());
    ASSERT_TRUE(webrtc::test::CreateDir(dir_path_));
    stream_.reset(new FileRotatingStream(dir_path_, file_prefix, max_file_size,
                                         num_log_files));
  }

  void TearDown() override {
    // On windows, open files can't be removed.
    stream_->Close();
    CleanupLogDirectory(*stream_);
    EXPECT_TRUE(webrtc::test::RemoveDir(dir_path_));

    stream_.reset();
  }

  // Writes the data to the stream and flushes it.
  void WriteAndFlush(const void* data, const size_t data_len) {
    EXPECT_EQ(SR_SUCCESS, stream_->WriteAll(data, data_len, nullptr, nullptr));
    EXPECT_TRUE(stream_->Flush());
  }

  // Checks that the stream reads in the expected contents and then returns an
  // end of stream result.
  void VerifyStreamRead(const char* expected_contents,
                        const size_t expected_length,
                        const std::string& dir_path,
                        const char* file_prefix) {
    std::unique_ptr<FileRotatingStream> stream;
    stream.reset(new FileRotatingStream(dir_path, file_prefix));
    ASSERT_TRUE(stream->Open());
    size_t read = 0;
    size_t stream_size = 0;
    EXPECT_TRUE(stream->GetSize(&stream_size));
    std::unique_ptr<uint8_t[]> buffer(new uint8_t[expected_length]);
    EXPECT_EQ(SR_SUCCESS,
              stream->ReadAll(buffer.get(), expected_length, &read, nullptr));
    EXPECT_EQ(0, memcmp(expected_contents, buffer.get(), expected_length));
    EXPECT_EQ(SR_EOS, stream->ReadAll(buffer.get(), 1, nullptr, nullptr));
    EXPECT_EQ(stream_size, read);
  }

  void VerifyFileContents(const char* expected_contents,
                          const size_t expected_length,
                          const std::string& file_path) {
    std::unique_ptr<uint8_t[]> buffer(new uint8_t[expected_length]);
    FileStream stream;
    ASSERT_TRUE(stream.Open(file_path, "r", nullptr));
    EXPECT_EQ(rtc::SR_SUCCESS,
              stream.ReadAll(buffer.get(), expected_length, nullptr, nullptr));
    EXPECT_EQ(0, memcmp(expected_contents, buffer.get(), expected_length));
    size_t file_size = 0;
    EXPECT_TRUE(stream.GetSize(&file_size));
    EXPECT_EQ(file_size, expected_length);
  }

  std::unique_ptr<FileRotatingStream> stream_;
  std::string dir_path_;
};

const char* MAYBE_FileRotatingStreamTest::kFilePrefix =
    "FileRotatingStreamTest";
const size_t MAYBE_FileRotatingStreamTest::kMaxFileSize = 2;

// Tests that stream state is correct before and after Open / Close.
TEST_F(MAYBE_FileRotatingStreamTest, State) {
  Init("FileRotatingStreamTestState", kFilePrefix, kMaxFileSize, 3);

  EXPECT_EQ(SS_CLOSED, stream_->GetState());
  ASSERT_TRUE(stream_->Open());
  EXPECT_EQ(SS_OPEN, stream_->GetState());
  stream_->Close();
  EXPECT_EQ(SS_CLOSED, stream_->GetState());
}

// Tests that nothing is written to file when data of length zero is written.
TEST_F(MAYBE_FileRotatingStreamTest, EmptyWrite) {
  Init("FileRotatingStreamTestEmptyWrite", kFilePrefix, kMaxFileSize, 3);

  ASSERT_TRUE(stream_->Open());
  WriteAndFlush("a", 0);

  std::string logfile_path = stream_->GetFilePath(0);
  FileStream stream;
  ASSERT_TRUE(stream.Open(logfile_path, "r", nullptr));
  size_t file_size = 0;
  EXPECT_TRUE(stream.GetSize(&file_size));
  EXPECT_EQ(0u, file_size);
}

// Tests that a write operation followed by a read returns the expected data
// and writes to the expected files.
TEST_F(MAYBE_FileRotatingStreamTest, WriteAndRead) {
  Init("FileRotatingStreamTestWriteAndRead", kFilePrefix, kMaxFileSize, 3);

  ASSERT_TRUE(stream_->Open());
  // The test is set up to create three log files of length 2. Write and check
  // contents.
  std::string messages[3] = {"aa", "bb", "cc"};
  for (size_t i = 0; i < arraysize(messages); ++i) {
    const std::string& message = messages[i];
    WriteAndFlush(message.c_str(), message.size());
    // Since the max log size is 2, we will be causing rotation. Read from the
    // next file.
    VerifyFileContents(message.c_str(), message.size(),
                       stream_->GetFilePath(1));
  }
  // Check that exactly three files exist.
  for (size_t i = 0; i < arraysize(messages); ++i) {
    EXPECT_TRUE(Filesystem::IsFile(stream_->GetFilePath(i)));
  }
  std::string message("d");
  WriteAndFlush(message.c_str(), message.size());
  for (size_t i = 0; i < arraysize(messages); ++i) {
    EXPECT_TRUE(Filesystem::IsFile(stream_->GetFilePath(i)));
  }
  // TODO(tkchin): Maybe check all the files in the dir.

  // Reopen for read.
  std::string expected_contents("bbccd");
  VerifyStreamRead(expected_contents.c_str(), expected_contents.size(),
                   dir_path_, kFilePrefix);
}

// Tests that writing data greater than the total capacity of the files
// overwrites the files correctly and is read correctly after.
TEST_F(MAYBE_FileRotatingStreamTest, WriteOverflowAndRead) {
  Init("FileRotatingStreamTestWriteOverflowAndRead", kFilePrefix, kMaxFileSize,
       3);
  ASSERT_TRUE(stream_->Open());
  // This should cause overflow across all three files, such that the first file
  // we wrote to also gets overwritten.
  std::string message("foobarbaz");
  WriteAndFlush(message.c_str(), message.size());
  std::string expected_file_contents("z");
  VerifyFileContents(expected_file_contents.c_str(),
                     expected_file_contents.size(), stream_->GetFilePath(0));
  std::string expected_stream_contents("arbaz");
  VerifyStreamRead(expected_stream_contents.c_str(),
                   expected_stream_contents.size(), dir_path_, kFilePrefix);
}

// Tests that the returned file paths have the right folder and prefix.
TEST_F(MAYBE_FileRotatingStreamTest, GetFilePath) {
  Init("FileRotatingStreamTestGetFilePath", kFilePrefix, kMaxFileSize, 20);
  for (auto i = 0; i < 20; ++i) {
    Pathname path(stream_->GetFilePath(i));
    EXPECT_EQ(0, path.folder().compare(dir_path_));
    EXPECT_EQ(0, path.filename().compare(0, strlen(kFilePrefix), kFilePrefix));
  }
}

#if defined (WEBRTC_ANDROID)
// Fails on Android: https://bugs.chromium.org/p/webrtc/issues/detail?id=4364.
#define MAYBE_CallSessionFileRotatingStreamTest \
    DISABLED_CallSessionFileRotatingStreamTest
#else
#define MAYBE_CallSessionFileRotatingStreamTest \
    CallSessionFileRotatingStreamTest
#endif

class MAYBE_CallSessionFileRotatingStreamTest : public ::testing::Test {
 protected:
  void Init(const std::string& dir_name, size_t max_total_log_size) {
    dir_path_ = webrtc::test::OutputPath();

    // Append per-test output path in order to run within gtest parallel.
    dir_path_.append(dir_name);
    dir_path_.push_back(Pathname::DefaultFolderDelimiter());
    ASSERT_TRUE(webrtc::test::CreateDir(dir_path_));
    stream_.reset(
        new CallSessionFileRotatingStream(dir_path_, max_total_log_size));
  }

  virtual void TearDown() {
    // On windows, open files can't be removed.
    stream_->Close();
    CleanupLogDirectory(*stream_);
    EXPECT_TRUE(webrtc::test::RemoveDir(dir_path_));

    stream_.reset();
  }

  // Writes the data to the stream and flushes it.
  void WriteAndFlush(const void* data, const size_t data_len) {
    EXPECT_EQ(SR_SUCCESS, stream_->WriteAll(data, data_len, nullptr, nullptr));
    EXPECT_TRUE(stream_->Flush());
  }

  // Checks that the stream reads in the expected contents and then returns an
  // end of stream result.
  void VerifyStreamRead(const char* expected_contents,
                        const size_t expected_length,
                        const std::string& dir_path) {
    std::unique_ptr<CallSessionFileRotatingStream> stream(
        new CallSessionFileRotatingStream(dir_path));
    ASSERT_TRUE(stream->Open());
    size_t read = 0;
    size_t stream_size = 0;
    EXPECT_TRUE(stream->GetSize(&stream_size));
    std::unique_ptr<uint8_t[]> buffer(new uint8_t[expected_length]);
    EXPECT_EQ(SR_SUCCESS,
              stream->ReadAll(buffer.get(), expected_length, &read, nullptr));
    EXPECT_EQ(0, memcmp(expected_contents, buffer.get(), expected_length));
    EXPECT_EQ(SR_EOS, stream->ReadAll(buffer.get(), 1, nullptr, nullptr));
    EXPECT_EQ(stream_size, read);
  }

  std::unique_ptr<CallSessionFileRotatingStream> stream_;
  std::string dir_path_;
};

// Tests that writing and reading to a stream with the smallest possible
// capacity works.
TEST_F(MAYBE_CallSessionFileRotatingStreamTest, WriteAndReadSmallest) {
  Init("CallSessionFileRotatingStreamTestWriteAndReadSmallest", 4);

  ASSERT_TRUE(stream_->Open());
  std::string message("abcde");
  WriteAndFlush(message.c_str(), message.size());
  std::string expected_contents("abe");
  VerifyStreamRead(expected_contents.c_str(), expected_contents.size(),
                   dir_path_);
}

// Tests that writing and reading to a stream with capacity lesser than 4MB
// behaves correctly.
TEST_F(MAYBE_CallSessionFileRotatingStreamTest, WriteAndReadSmall) {
  Init("CallSessionFileRotatingStreamTestWriteAndReadSmall", 8);

  ASSERT_TRUE(stream_->Open());
  std::string message("123456789");
  WriteAndFlush(message.c_str(), message.size());
  std::string expected_contents("1234789");
  VerifyStreamRead(expected_contents.c_str(), expected_contents.size(),
                   dir_path_);
}

// Tests that writing and reading to a stream with capacity greater than 4MB
// behaves correctly.
TEST_F(MAYBE_CallSessionFileRotatingStreamTest, WriteAndReadLarge) {
  Init("CallSessionFileRotatingStreamTestWriteAndReadLarge", 6 * 1024 * 1024);

  ASSERT_TRUE(stream_->Open());
  const size_t buffer_size = 1024 * 1024;
  std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
  for (int i = 0; i < 8; i++) {
    memset(buffer.get(), i, buffer_size);
    EXPECT_EQ(SR_SUCCESS,
              stream_->WriteAll(buffer.get(), buffer_size, nullptr, nullptr));
  }

  stream_.reset(new CallSessionFileRotatingStream(dir_path_));
  ASSERT_TRUE(stream_->Open());
  std::unique_ptr<uint8_t[]> expected_buffer(new uint8_t[buffer_size]);
  int expected_vals[] = {0, 1, 2, 6, 7};
  for (size_t i = 0; i < arraysize(expected_vals); ++i) {
    memset(expected_buffer.get(), expected_vals[i], buffer_size);
    EXPECT_EQ(SR_SUCCESS,
              stream_->ReadAll(buffer.get(), buffer_size, nullptr, nullptr));
    EXPECT_EQ(0, memcmp(buffer.get(), expected_buffer.get(), buffer_size));
  }
  EXPECT_EQ(SR_EOS, stream_->ReadAll(buffer.get(), 1, nullptr, nullptr));
}

// Tests that writing and reading to a stream where only the first file is
// written to behaves correctly.
TEST_F(MAYBE_CallSessionFileRotatingStreamTest, WriteAndReadFirstHalf) {
  Init("CallSessionFileRotatingStreamTestWriteAndReadFirstHalf",
       6 * 1024 * 1024);
  ASSERT_TRUE(stream_->Open());
  const size_t buffer_size = 1024 * 1024;
  std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
  for (int i = 0; i < 2; i++) {
    memset(buffer.get(), i, buffer_size);
    EXPECT_EQ(SR_SUCCESS,
              stream_->WriteAll(buffer.get(), buffer_size, nullptr, nullptr));
  }

  stream_.reset(new CallSessionFileRotatingStream(dir_path_));
  ASSERT_TRUE(stream_->Open());
  std::unique_ptr<uint8_t[]> expected_buffer(new uint8_t[buffer_size]);
  int expected_vals[] = {0, 1};
  for (size_t i = 0; i < arraysize(expected_vals); ++i) {
    memset(expected_buffer.get(), expected_vals[i], buffer_size);
    EXPECT_EQ(SR_SUCCESS,
              stream_->ReadAll(buffer.get(), buffer_size, nullptr, nullptr));
    EXPECT_EQ(0, memcmp(buffer.get(), expected_buffer.get(), buffer_size));
  }
  EXPECT_EQ(SR_EOS, stream_->ReadAll(buffer.get(), 1, nullptr, nullptr));
}

}  // namespace rtc
