// Copyright 2020 The PDFium Authors. All rights reserved.
// 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
