// Copyright 2020 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TODO(crbug.com/1009553): Remove this wrapper after finding a way to plumb a
// workable temporary path into googletest on Android.

// This wrapper lets us compile gtest-port.cc without its stream redirection
// code. We replace this code with a variant that works on all Chrome platforms.
// This is a temporary workaround until we get good code upstream.
//
// Stream redirection requires the ability to create files in a temporary
// directory. Traditionally, this directory has been /sdcard on Android.
// Commit bf0fe874a27bd6c9a4a35b98e662d2d02f8879a2 changed the Android
// directory to /data/local/tmp, which is not writable in Chrome's testing
// setup. We work around this problem by using the old code for now.
//
// It is tempting to consider disabling the stream redirection code altogether,
// by setting GTEST_HAS_STREAM_REDIRECTION to 0 in googletest's BUILD.gn.
// This breaks gtest-death-test.cc, which assumes the existence of
// testing::internal::{GetCapturedStderr,CaptureStderr} without any macro
// checking.

#define GTEST_HAS_STREAM_REDIRECTION 0
#include "third_party/googletest/src/googletest/src/gtest-port.cc"

namespace testing {
namespace internal {

// Object that captures an output stream (stdout/stderr).
class CapturedStream {
 public:
  // The ctor redirects the stream to a temporary file.
  explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
    std::string temp_dir = ::testing::TempDir();

    // testing::TempDir() should return a directory with a path separator.
    // However, this rule was documented fairly recently, so we normalize across
    // implementations with and without a trailing path separator.
    if (temp_dir.back() != GTEST_PATH_SEP_[0])
      temp_dir.push_back(GTEST_PATH_SEP_[0]);

#if GTEST_OS_WINDOWS
    char temp_file_path[MAX_PATH + 1] = {'\0'};  // NOLINT
    const UINT success = ::GetTempFileNameA(temp_dir.c_str(), "gtest_redir",
                                            0,  // Generate unique file name.
                                            temp_file_path);
    GTEST_CHECK_(success != 0)
        << "Unable to create a temporary file in " << temp_dir;
    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
    GTEST_CHECK_(captured_fd != -1)
        << "Unable to open temporary file " << temp_file_path;
    filename_ = temp_file_path;
#else
    std::string name_template = temp_dir + "gtest_captured_stream.XXXXXX";

    // mkstemp() modifies the string bytes in place, and does not go beyond the
    // string's length. This results in well-defined behavior in C++17.
    //
    // The const_cast is needed below C++17. The constraints on std::string
    // implementations in C++11 and above make assumption behind the const_cast
    // fairly safe.
    const int captured_fd = ::mkstemp(const_cast<char*>(name_template.data()));
    GTEST_CHECK_(captured_fd != -1)
        << "Failed to create tmp file " << name_template
        << " for test; does the test have write access to the directory?";
    filename_ = std::move(name_template);
#endif  // GTEST_OS_WINDOWS
    fflush(nullptr);
    dup2(captured_fd, fd_);
    close(captured_fd);
  }

  ~CapturedStream() { remove(filename_.c_str()); }

  std::string GetCapturedString() {
    if (uncaptured_fd_ != -1) {
      // Restores the original stream.
      fflush(nullptr);
      dup2(uncaptured_fd_, fd_);
      close(uncaptured_fd_);
      uncaptured_fd_ = -1;
    }

    FILE* const file = posix::FOpen(filename_.c_str(), "r");
    if (file == nullptr) {
      GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_
                        << " for capturing stream.";
    }
    const std::string content = ReadEntireFile(file);
    posix::FClose(file);
    return content;
  }

 private:
  const int fd_;  // A stream to capture.
  int uncaptured_fd_;
  // Name of the temporary file holding the stderr output.
  ::std::string filename_;

  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
};

GTEST_DISABLE_MSC_DEPRECATED_POP_()

static CapturedStream* g_captured_stderr = nullptr;
static CapturedStream* g_captured_stdout = nullptr;

// Starts capturing an output stream (stdout/stderr).
static void CaptureStream(int fd,
                          const char* stream_name,
                          CapturedStream** stream) {
  if (*stream != nullptr) {
    GTEST_LOG_(FATAL) << "Only one " << stream_name
                      << " capturer can exist at a time.";
  }
  *stream = new CapturedStream(fd);
}

// Stops capturing the output stream and returns the captured string.
static std::string GetCapturedStream(CapturedStream** captured_stream) {
  const std::string content = (*captured_stream)->GetCapturedString();

  delete *captured_stream;
  *captured_stream = nullptr;

  return content;
}

// Starts capturing stdout.
void CaptureStdout() {
  CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
}

// Starts capturing stderr.
void CaptureStderr() {
  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
}

// Stops capturing stdout and returns the captured string.
std::string GetCapturedStdout() {
  return GetCapturedStream(&g_captured_stdout);
}

// Stops capturing stderr and returns the captured string.
std::string GetCapturedStderr() {
  return GetCapturedStream(&g_captured_stderr);
}

}  // namespace internal
}  // namespace testing
