/*
 *  Copyright (c) 2017 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 "api/rtc_event_log_output_file.h"

#include <fstream>
#include <iterator>
#include <memory>
#include <string>

#include "rtc_base/checks.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {

class RtcEventLogOutputFileTest : public ::testing::Test {
 public:
  RtcEventLogOutputFileTest() : output_file_name_(GetOutputFilePath()) {
    // Ensure no leftovers from previous runs, which might not have terminated
    // in an orderly fashion.
    remove(output_file_name_.c_str());
  }

  ~RtcEventLogOutputFileTest() override { remove(output_file_name_.c_str()); }

 protected:
  std::string GetOutputFilePath() const {
    auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
    return test::OutputPath() + test_info->test_case_name() + test_info->name();
  }

  std::string GetOutputFileContents() const {
    std::ifstream file(output_file_name_,
                       std::ios_base::in | std::ios_base::binary);
    RTC_CHECK(file.is_open());
    RTC_CHECK(file.good());
    std::string file_str((std::istreambuf_iterator<char>(file)),
                         std::istreambuf_iterator<char>());
    return file_str;
  }

  const std::string output_file_name_;
};

TEST_F(RtcEventLogOutputFileTest, NonDefectiveOutputsStartOutActive) {
  auto output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_);
  EXPECT_TRUE(output_file->IsActive());
}

TEST_F(RtcEventLogOutputFileTest, DefectiveOutputsStartOutInactive) {
  const std::string illegal_filename = "/////////";
  auto output_file = std::make_unique<RtcEventLogOutputFile>(illegal_filename);
  EXPECT_FALSE(output_file->IsActive());
}

// Sanity over opening a file (by filename) with an unlimited size.
TEST_F(RtcEventLogOutputFileTest, UnlimitedOutputFile) {
  const std::string output_str = "one two three";

  auto output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_);
  output_file->Write(output_str);
  output_file.reset();  // Closing the file flushes the buffer to disk.

  EXPECT_EQ(GetOutputFileContents(), output_str);
}

// Do not allow writing more bytes to the file than
TEST_F(RtcEventLogOutputFileTest, LimitedOutputFileCappedToCapacity) {
  // Fit two bytes, then the third should be rejected.
  auto output_file =
      std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);

  output_file->Write("1");
  output_file->Write("2");
  output_file->Write("3");
  // Unsuccessful writes close the file; no need to delete the output to flush.

  EXPECT_EQ(GetOutputFileContents(), "12");
}

// Make sure that calls to Write() either write everything to the file, or
// nothing (short of underlying issues in the module that handles the file,
// which would be beyond our control).
TEST_F(RtcEventLogOutputFileTest, DoNotWritePartialLines) {
  const std::string output_str_1 = "0123456789";
  const std::string output_str_2 = "abcdefghij";

  // Set a file size limit just shy of fitting the entire second line.
  const size_t size_limit = output_str_1.length() + output_str_2.length() - 1;
  auto output_file =
      std::make_unique<RtcEventLogOutputFile>(output_file_name_, size_limit);

  output_file->Write(output_str_1);
  output_file->Write(output_str_2);
  // Unsuccessful writes close the file; no need to delete the output to flush.

  EXPECT_EQ(GetOutputFileContents(), output_str_1);
}

TEST_F(RtcEventLogOutputFileTest, UnsuccessfulWriteReturnsFalse) {
  auto output_file =
      std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
  EXPECT_FALSE(output_file->Write("abc"));
}

TEST_F(RtcEventLogOutputFileTest, SuccessfulWriteReturnsTrue) {
  auto output_file =
      std::make_unique<RtcEventLogOutputFile>(output_file_name_, 3);
  EXPECT_TRUE(output_file->Write("abc"));
}

// Even if capacity is reached, a successful write leaves the output active.
TEST_F(RtcEventLogOutputFileTest, FileStillActiveAfterSuccessfulWrite) {
  auto output_file =
      std::make_unique<RtcEventLogOutputFile>(output_file_name_, 3);
  ASSERT_TRUE(output_file->Write("abc"));
  EXPECT_TRUE(output_file->IsActive());
}

// Unsuccessful writes switch the output to inactive, even if capacity has
// not yet been reached.
TEST_F(RtcEventLogOutputFileTest, FileInactiveAfterUnsuccessfulWrite) {
  auto output_file =
      std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
  ASSERT_FALSE(output_file->Write("abc"));
  EXPECT_FALSE(output_file->IsActive());
}

TEST_F(RtcEventLogOutputFileTest, AllowReasonableFileSizeLimits) {
  auto output_file = std::make_unique<RtcEventLogOutputFile>(
      output_file_name_, RtcEventLogOutputFile::kMaxReasonableFileSize);
  EXPECT_TRUE(output_file->IsActive());
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
class RtcEventLogOutputFileDeathTest : public RtcEventLogOutputFileTest {};

TEST_F(RtcEventLogOutputFileDeathTest, WritingToInactiveFileForbidden) {
  RtcEventLogOutputFile output_file(output_file_name_, 2);
  ASSERT_FALSE(output_file.Write("abc"));
  ASSERT_FALSE(output_file.IsActive());
  EXPECT_DEATH(output_file.Write("abc"), "");
}

TEST_F(RtcEventLogOutputFileDeathTest, DisallowUnreasonableFileSizeLimits) {
  // Keeping in a temporary unique_ptr to make it clearer that the death is
  // triggered by construction, not destruction.
  std::unique_ptr<RtcEventLogOutputFile> output_file;
  auto create_output_file = [&] {
    const size_t unreasonable_size =
        RtcEventLogOutputFile::kMaxReasonableFileSize + 1;
    output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_,
                                                          unreasonable_size);
  };
  EXPECT_DEATH(create_output_file(), "");
}
#endif

}  // namespace webrtc
