// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Test wrapper implementation for Windows.
// Design:
// https://github.com/laszlocsomor/proposals/blob/win-test-runner/designs/2018-07-18-windows-native-test-runner.md

#include "tools/test/windows/tw.h"

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>

#include <errno.h>
#include <limits.h>  // INT_MAX
#include <lmcons.h>  // UNLEN
#include <string.h>
#include <sys/types.h>
#include <wchar.h>

#include <algorithm>
#include <cstdio>
#include <fstream>
#include <functional>
#include <iomanip>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "src/main/cpp/util/file_platform.h"
#include "src/main/cpp/util/path_platform.h"
#include "src/main/cpp/util/strings.h"
#include "src/main/native/windows/file.h"
#include "src/main/native/windows/process.h"
#include "src/main/native/windows/util.h"
#include "src/tools/launcher/util/launcher_util.h"
#include "third_party/ijar/common.h"
#include "third_party/ijar/platform_utils.h"
#include "third_party/ijar/zip.h"
#include "tools/cpp/runfiles/runfiles.h"

namespace bazel {
namespace tools {
namespace test_wrapper {
namespace {

class Defer {
 public:
  explicit Defer(std::function<void()> f) : f_(f) {}
  ~Defer() { f_(); }

  void DoNow() {
    f_();
    f_ = kEmpty;
  }

 private:
  std::function<void()> f_;
  static const std::function<void()> kEmpty;
};

const std::function<void()> Defer::kEmpty = []() {};

// Streams data from an input to two outputs.
// Inspired by tee(1) in the GNU coreutils.
class TeeImpl : Tee {
 public:
  // Creates a background thread to stream data from `input` to the two outputs.
  // The thread terminates when ReadFile fails on the input (e.g. the input is
  // the reading end of a pipe and the writing end is closed) or when WriteFile
  // fails on one of the outputs (e.g. the same output handle is closed
  // elsewhere).
  static bool Create(bazel::windows::AutoHandle* input,
                     bazel::windows::AutoHandle* output1,
                     bazel::windows::AutoHandle* output2,
                     std::unique_ptr<Tee>* result);

 private:
  static DWORD WINAPI ThreadFunc(LPVOID lpParam);

  TeeImpl(bazel::windows::AutoHandle* input,
          bazel::windows::AutoHandle* output1,
          bazel::windows::AutoHandle* output2)
      : input_(input), output1_(output1), output2_(output2) {}
  TeeImpl(const TeeImpl&) = delete;
  TeeImpl& operator=(const TeeImpl&) = delete;

  bool MainFunc() const;

  bazel::windows::AutoHandle input_;
  bazel::windows::AutoHandle output1_;
  bazel::windows::AutoHandle output2_;
};

// Buffered input stream (based on a Windows HANDLE) with peek-ahead support.
//
// This class uses two consecutive "pages" where it buffers data from the
// underlying HANDLE (wrapped in an AutoHandle). Both pages are always loaded
// with data until there's no more data to read.
//
// The "active" page is the one where the read cursor is pointing. The other
// page is the next one to be read once the client moves the read cursor beyond
// the end of the active page.
//
// The client advances the read cursor with Advance(). When the cursor reaches
// the end of the active page, the other page becomes the active one (whose data
// is already buffered), and the old active page is loaded with new data from
// the underlying file.
class IFStreamImpl : IFStream {
 public:
  // Creates a new IFStream.
  //
  // If successful, then takes ownership of the HANDLE in 'handle', and returns
  // a new IFStream pointer. Otherwise leaves 'handle' alone and returns
  // nullptr.
  static IFStream* Create(HANDLE handle, DWORD page_size = 0x100000 /* 1 MB */);

  int Get() override;
  DWORD Peek(DWORD n, uint8_t* out) const override;

 private:
  HANDLE handle_;
  const std::unique_ptr<uint8_t[]> pages_;
  const DWORD page_size_;
  DWORD pos_, end_, next_size_;

  IFStreamImpl(HANDLE handle, std::unique_ptr<uint8_t[]>&& pages, DWORD n,
               DWORD page_size)
      : handle_(handle),
        pages_(std::move(pages)),
        page_size_(page_size),
        pos_(0),
        end_(n < page_size ? n : page_size),
        next_size_(n < page_size
                       ? 0
                       : (n < page_size * 2 ? n - page_size : page_size)) {}
};

// A lightweight path abstraction that stores a Unicode Windows path.
//
// The class allows extracting the underlying path as a (immutable) string so
// it's easy to pass the path to WinAPI functions, but the class does not allow
// mutating the unterlying path so it's safe to pass around Path objects.
class Path {
 public:
  Path() {}
  Path(const Path& other) : path_(other.path_) {}
  Path(Path&& other) : path_(std::move(other.path_)) {}
  Path& operator=(const Path& other) = delete;
  const std::wstring& Get() const { return path_; }
  bool Set(const std::wstring& path);

  // Makes this path absolute.
  // Returns true if the path was changed (i.e. was not absolute before).
  // Returns false and has no effect if this path was empty or already absolute.
  bool Absolutize(const Path& cwd);

  Path Dirname() const;

 private:
  std::wstring path_;
};

struct UndeclaredOutputs {
  Path root;
  Path zip;
  Path manifest;
  Path annotations;
  Path annotations_dir;
};

struct Duration {
  static constexpr int kMax = INT_MAX;

  int seconds;

  bool FromString(const wchar_t* str);
};

void WriteStdout(const std::string& s) {
  DWORD written;
  WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), s.c_str(), s.size(), &written,
            NULL);
}

void LogError(const int line) {
  std::stringstream ss;
  ss << "ERROR(" << __FILE__ << ":" << line << ")" << std::endl;
  WriteStdout(ss.str());
}

void LogError(const int line, const std::string& msg) {
  std::stringstream ss;
  ss << "ERROR(" << __FILE__ << ":" << line << ") " << msg << std::endl;
  WriteStdout(ss.str());
}

void LogError(const int line, const std::wstring& msg) {
  std::string acp_msg;
  if (blaze_util::WcsToAcp(msg, &acp_msg)) {
    LogError(line, acp_msg);
  }
}

void LogErrorWithValue(const int line, const std::string& msg, DWORD value) {
  std::stringstream ss;
  ss << "value: " << value << " (0x";
  ss.setf(std::ios_base::hex, std::ios_base::basefield);
  ss << std::setw(8) << std::setfill('0') << value << "): ";
  ss.setf(std::ios_base::dec, std::ios_base::basefield);
  ss << msg;
  LogError(line, ss.str());
}

void LogErrorWithValue(const int line, const std::wstring& msg, DWORD value) {
  std::string acp_msg;
  if (blaze_util::WcsToAcp(msg, &acp_msg)) {
    LogErrorWithValue(line, acp_msg, value);
  }
}

void LogErrorWithArg(const int line, const std::string& msg,
                     const std::string& arg) {
  std::stringstream ss;
  ss << msg << " (arg: " << arg << ")";
  LogError(line, ss.str());
}

void LogErrorWithArg(const int line, const std::string& msg,
                     const std::wstring& arg) {
  std::string acp_arg;
  if (blaze_util::WcsToAcp(arg, &acp_arg)) {
    LogErrorWithArg(line, msg, acp_arg);
  }
}

void LogErrorWithArg2(const int line, const std::string& msg,
                      const std::string& arg1, const std::string& arg2) {
  std::stringstream ss;
  ss << msg << " (arg1: " << arg1 << ", arg2: " << arg2 << ")";
  LogError(line, ss.str());
}

void LogErrorWithArg2(const int line, const std::string& msg,
                      const std::wstring& arg1, const std::wstring& arg2) {
  std::string acp_arg1, acp_arg2;
  if (blaze_util::WcsToAcp(arg1, &acp_arg1) &&
      blaze_util::WcsToAcp(arg2, &acp_arg2)) {
    LogErrorWithArg2(line, msg, acp_arg1, acp_arg2);
  }
}

void LogErrorWithArgAndValue(const int line, const std::string& msg,
                             const std::string& arg, DWORD value) {
  std::stringstream ss;
  ss << "value: " << value << " (0x";
  ss.setf(std::ios_base::hex, std::ios_base::basefield);
  ss << std::setw(8) << std::setfill('0') << value << "), arg: ";
  ss.setf(std::ios_base::dec, std::ios_base::basefield);
  ss << arg << ": " << msg;
  LogError(line, ss.str());
}

void LogErrorWithArgAndValue(const int line, const std::string& msg,
                             const std::wstring& arg, DWORD value) {
  std::string acp_arg;
  if (blaze_util::WcsToAcp(arg, &acp_arg)) {
    LogErrorWithArgAndValue(line, msg, acp_arg, value);
  }
}

std::wstring AddUncPrefixMaybe(const Path& p) {
  return bazel::windows::AddUncPrefixMaybe(p.Get());
}

std::wstring RemoveUncPrefixMaybe(const Path& p) {
  return bazel::windows::RemoveUncPrefixMaybe(p.Get());
}

inline bool CreateDirectories(const Path& path) {
  blaze_util::MakeDirectoriesW(AddUncPrefixMaybe(path), 0777);
  return true;
}

inline bool ToInt(const wchar_t* s, int* result) {
  return std::swscanf(s, L"%d", result) == 1;
}

bool WcsToAcp(const std::wstring& wcs, std::string* acp) {
  uint32_t err;
  if (!blaze_util::WcsToAcp(wcs, acp, &err)) {
    LogErrorWithArgAndValue(__LINE__, "Failed to convert string", wcs, err);
    return false;
  }
  return true;
}

// Converts a Windows-style path to a mixed (Unix-Windows) style.
// The path is mixed-style because it is a Windows path (begins with a drive
// letter) but uses forward slashes as directory separators.
// We must export envvars as mixed style path because some tools confuse the
// backslashes in Windows paths for Unix-style escape characters.
std::wstring AsMixedPath(const std::wstring& path) {
  std::wstring value = path;
  std::replace(value.begin(), value.end(), L'\\', L'/');
  return value;
}

// Gets an environment variable's value.
// Returns:
// - true, if the envvar is defined and successfully fetched, or it's empty or
//   undefined
// - false, if some error occurred
bool GetEnv(const wchar_t* name, std::wstring* result) {
  static constexpr size_t kSmallBuf = MAX_PATH;
  WCHAR value[kSmallBuf];
  DWORD size = GetEnvironmentVariableW(name, value, kSmallBuf);
  DWORD err = GetLastError();
  if (size == 0 && err == ERROR_ENVVAR_NOT_FOUND) {
    result->clear();
    return true;
  } else if (0 < size && size < kSmallBuf) {
    *result = value;
    return true;
  } else if (size >= kSmallBuf) {
    std::unique_ptr<WCHAR[]> value_big(new WCHAR[size]);
    GetEnvironmentVariableW(name, value_big.get(), size);
    *result = value_big.get();
    return true;
  } else {
    LogErrorWithArgAndValue(__LINE__, "Failed to read envvar", name, err);
    return false;
  }
}

// Gets an environment variable's value as a Path.
// Returns:
// - true, if the envvar is defined and successfully fetched, or it's empty or
//   undefined
// - false, if some error occurred
bool GetPathEnv(const wchar_t* name, Path* result) {
  std::wstring value;
  if (!GetEnv(name, &value)) {
    LogError(__LINE__, name);
    return false;
  }
  return result->Set(value);
}

// Gets an environment variable's value as integer and as the original string.
// Returns:
// - true, if the envvar is defined and successfully fetched, or it's empty or
//   undefined (in that case 'as_int' will be 0 and 'as_wstr' empty)
// - false, if ToInt cannot parse the string to an int, or some error occurred
bool GetIntEnv(const wchar_t* name, std::wstring* as_wstr, int* as_int) {
  *as_int = 0;
  if (!GetEnv(name, as_wstr) ||
      (!as_wstr->empty() && !ToInt(as_wstr->c_str(), as_int))) {
    LogError(__LINE__, name);
    return false;
  }
  return true;
}

bool SetEnv(const wchar_t* name, const std::wstring& value) {
  if (SetEnvironmentVariableW(name, value.c_str()) != 0) {
    return true;
  } else {
    DWORD err = GetLastError();
    LogErrorWithArgAndValue(__LINE__, "Failed to set envvar", name, err);
    return false;
  }
}

bool SetPathEnv(const wchar_t* name, const Path& path) {
  return SetEnv(name, AsMixedPath(path.Get()));
}

bool UnsetEnv(const wchar_t* name) {
  if (SetEnvironmentVariableW(name, NULL) != 0) {
    return true;
  } else {
    DWORD err = GetLastError();
    LogErrorWithArgAndValue(__LINE__, "Failed to unset envvar", name, err);
    return false;
  }
}

bool GetCwd(Path* result) {
  static constexpr size_t kSmallBuf = MAX_PATH;
  WCHAR value[kSmallBuf];
  DWORD size = GetCurrentDirectoryW(kSmallBuf, value);
  DWORD err = GetLastError();
  if (size > 0 && size < kSmallBuf) {
    return result->Set(value);
  } else if (size >= kSmallBuf) {
    std::unique_ptr<WCHAR[]> value_big(new WCHAR[size]);
    GetCurrentDirectoryW(size, value_big.get());
    return result->Set(value_big.get());
  } else {
    LogErrorWithValue(__LINE__, "Failed to get current directory", err);
    return false;
  }
}

// Set USER as required by the Bazel Test Encyclopedia.
bool ExportUserName() {
  std::wstring value;
  if (!GetEnv(L"USER", &value)) {
    return false;
  }
  if (!value.empty()) {
    // Respect the value passed by Bazel via --test_env.
    return true;
  }
  WCHAR buffer[UNLEN + 1];
  DWORD len = UNLEN + 1;
  if (GetUserNameW(buffer, &len) == 0) {
    DWORD err = GetLastError();
    LogErrorWithValue(__LINE__, "Failed to query user name", err);
    return false;
  }
  return SetEnv(L"USER", buffer);
}

// Gets a path envvar, and re-exports it as an absolute path.
// Returns:
// - true, if the envvar was defined, and was already absolute or was
//   successfully absolutized and re-exported
// - false, if the envvar was undefined or empty, or it could not be absolutized
//   or re-exported
bool ExportAbsolutePathEnv(const wchar_t* envvar, const Path& cwd,
                           Path* result) {
  if (!GetPathEnv(envvar, result)) {
    LogErrorWithArg(__LINE__, "Failed to get envvar", envvar);
    return false;
  }
  if (result->Get().empty()) {
    LogErrorWithArg(__LINE__, "Envvar was empty", envvar);
    return false;
  }
  if (result->Absolutize(cwd) && !SetPathEnv(envvar, *result)) {
    LogErrorWithArg2(__LINE__, "Failed to set absolutized envvar", envvar,
                     result->Get());
    return false;
  }
  return true;
}

// Set TEST_SRCDIR as required by the Bazel Test Encyclopedia.
bool ExportSrcPath(const Path& cwd, Path* result) {
  if (!ExportAbsolutePathEnv(L"TEST_SRCDIR", cwd, result)) {
    LogError(__LINE__, "Failed to export TEST_SRCDIR");
    return false;
  }
  return true;
}

// Set TEST_TMPDIR as required by the Bazel Test Encyclopedia.
bool ExportTmpPath(const Path& cwd, Path* result) {
  if (!ExportAbsolutePathEnv(L"TEST_TMPDIR", cwd, result)) {
    LogError(__LINE__, "Failed to export TEST_TMPDIR");
    return false;
  }
  // Create the test temp directory, which may not exist on the remote host when
  // doing a remote build.
  return CreateDirectories(*result);
}

// Set HOME as required by the Bazel Test Encyclopedia.
bool ExportHome(const Path& test_tmpdir) {
  Path home;
  if (!GetPathEnv(L"HOME", &home)) {
    return false;
  }
  if (blaze_util::IsAbsolute(home.Get())) {
    // Respect the user-defined HOME in case they set passed it with
    // --test_env=HOME or --test_env=HOME=C:\\foo
    return true;
  } else {
    // Set TEST_TMPDIR as required by the Bazel Test Encyclopedia.
    return SetPathEnv(L"HOME", test_tmpdir);
  }
}

bool ExportRunfiles(const Path& cwd, const Path& test_srcdir) {
  Path runfiles_dir;
  if (!GetPathEnv(L"RUNFILES_DIR", &runfiles_dir) ||
      (runfiles_dir.Absolutize(cwd) &&
       !SetPathEnv(L"RUNFILES_DIR", runfiles_dir))) {
    return false;
  }

  // TODO(ulfjack): Standardize on RUNFILES_DIR and remove the
  // {JAVA,PYTHON}_RUNFILES vars.
  Path java_rf, py_rf;
  if (!GetPathEnv(L"JAVA_RUNFILES", &java_rf) ||
      (java_rf.Absolutize(cwd) && !SetPathEnv(L"JAVA_RUNFILES", java_rf)) ||
      !GetPathEnv(L"PYTHON_RUNFILES", &py_rf) ||
      (py_rf.Absolutize(cwd) && !SetPathEnv(L"PYTHON_RUNFILES", py_rf))) {
    return false;
  }

  std::wstring mf_only_str;
  int mf_only_value = 0;
  if (!GetIntEnv(L"RUNFILES_MANIFEST_ONLY", &mf_only_str, &mf_only_value)) {
    return false;
  }
  if (mf_only_value == 1) {
    // If RUNFILES_MANIFEST_ONLY is set to 1 then test programs should use the
    // manifest file to find their runfiles.
    Path runfiles_mf;
    if (!runfiles_mf.Set(test_srcdir.Get() + L"\\MANIFEST") ||
        !SetPathEnv(L"RUNFILES_MANIFEST_FILE", runfiles_mf)) {
      return false;
    }
  }

  return true;
}

bool ExportShardStatusFile(const Path& cwd) {
  Path status_file;
  if (!GetPathEnv(L"TEST_SHARD_STATUS_FILE", &status_file) ||
      (!status_file.Get().empty() && status_file.Absolutize(cwd) &&
       !SetPathEnv(L"TEST_SHARD_STATUS_FILE", status_file))) {
    return false;
  }

  return status_file.Get().empty() ||
         // The test shard status file is only set for sharded tests.
         CreateDirectories(status_file.Dirname());
}

bool ExportGtestVariables(const Path& test_tmpdir) {
  // # Tell googletest about Bazel sharding.
  std::wstring total_shards_str;
  int total_shards_value = 0;
  if (!GetIntEnv(L"TEST_TOTAL_SHARDS", &total_shards_str,
                 &total_shards_value)) {
    return false;
  }
  if (total_shards_value > 0) {
    std::wstring shard_index;
    if (!GetEnv(L"TEST_SHARD_INDEX", &shard_index) ||
        !SetEnv(L"GTEST_SHARD_INDEX", shard_index) ||
        !SetEnv(L"GTEST_TOTAL_SHARDS", total_shards_str)) {
      return false;
    }
  }
  return SetPathEnv(L"GTEST_TMP_DIR", test_tmpdir);
}

bool ExportMiscEnvvars(const Path& cwd) {
  for (const wchar_t* name :
       {L"TEST_INFRASTRUCTURE_FAILURE_FILE", L"TEST_LOGSPLITTER_OUTPUT_FILE",
        L"TEST_PREMATURE_EXIT_FILE", L"TEST_UNUSED_RUNFILES_LOG_FILE",
        L"TEST_WARNINGS_OUTPUT_FILE"}) {
    Path value;
    if (!GetPathEnv(name, &value) ||
        (value.Absolutize(cwd) && !SetPathEnv(name, value))) {
      return false;
    }
  }
  return true;
}

bool _GetFileListRelativeTo(const std::wstring& unc_root,
                            const std::wstring& subdir, int depth_limit,
                            std::vector<FileInfo>* result) {
  const std::wstring full_subdir =
      unc_root + (subdir.empty() ? L"" : (L"\\" + subdir)) + L"\\*";
  WIN32_FIND_DATAW info;
  HANDLE handle = FindFirstFileW(full_subdir.c_str(), &info);
  if (handle == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError();
    if (err == ERROR_FILE_NOT_FOUND) {
      // No files found, nothing to do.
      return true;
    }
    LogErrorWithArgAndValue(__LINE__, "Failed to list directory contents",
                            full_subdir, err);
    return false;
  }

  Defer close_handle([handle]() { FindClose(handle); });
  static const std::wstring kDot(1, L'.');
  static const std::wstring kDotDot(2, L'.');
  std::vector<std::wstring> subdirectories;
  while (true) {
    if (kDot != info.cFileName && kDotDot != info.cFileName) {
      std::wstring rel_path =
          subdir.empty() ? info.cFileName : (subdir + L"\\" + info.cFileName);
      if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
        if (depth_limit != 0) {
          // depth_limit is negative ==> unlimited depth
          // depth_limit is zero     ==> do not recurse further
          // depth_limit is positive ==> recurse further
          subdirectories.push_back(rel_path);
        }
        result->push_back(FileInfo(rel_path));
      } else {
        if (info.nFileSizeHigh > 0 || info.nFileSizeLow > INT_MAX) {
          // devtools_ijar::Stat::total_size is declared as `int`, so the file
          // size limit is INT_MAX. Additionally we limit the files to be below
          // 4 GiB, not only because int is typically 4 bytes long, but also
          // because such huge files are unreasonably large as an undeclared
          // output.
          LogErrorWithArgAndValue(__LINE__, "File is too large to archive",
                                  rel_path, 0);
          return false;
        }

        result->push_back(FileInfo(rel_path,
                                   // File size is already validated to be
                                   // smaller than min(INT_MAX, 4 GiB)
                                   static_cast<int>(info.nFileSizeLow)));
      }
    }
    if (FindNextFileW(handle, &info) == 0) {
      DWORD err = GetLastError();
      if (err == ERROR_NO_MORE_FILES) {
        break;
      }
      LogErrorWithArgAndValue(__LINE__,
                              "Failed to get next element in directory",
                              unc_root + L"\\" + subdir, err);
      return false;
    }
  }
  close_handle.DoNow();

  if (depth_limit != 0) {
    // depth_limit is negative ==> unlimited depth
    // depth_limit is zero     ==> do not recurse further
    // depth_limit is positive ==> recurse further
    for (const auto& s : subdirectories) {
      if (!_GetFileListRelativeTo(
              unc_root, s, depth_limit > 0 ? depth_limit - 1 : depth_limit,
              result)) {
        return false;
      }
    }
  }
  return true;
}

bool GetFileListRelativeTo(const Path& root, std::vector<FileInfo>* result,
                           int depth_limit = -1) {
  if (!blaze_util::IsAbsolute(root.Get())) {
    LogError(__LINE__, "Root should be absolute");
    return false;
  }

  return _GetFileListRelativeTo(AddUncPrefixMaybe(root), std::wstring(),
                                depth_limit, result);
}

bool ToZipEntryPaths(const Path& root, const std::vector<FileInfo>& files,
                     ZipEntryPaths* result) {
  std::string acp_root;
  if (!WcsToAcp(AsMixedPath(RemoveUncPrefixMaybe(root)), &acp_root)) {
    LogErrorWithArg(__LINE__, "Failed to convert path", root.Get());
    return false;
  }

  // Convert all UTF-16 paths to ANSI paths.
  std::vector<std::string> acp_file_list;
  acp_file_list.reserve(files.size());
  for (const auto& e : files) {
    std::string acp_path;
    if (!WcsToAcp(AsMixedPath(e.RelativePath()), &acp_path)) {
      LogErrorWithArg(__LINE__, "Failed to convert path", e.RelativePath());
      return false;
    }
    if (e.IsDirectory()) {
      acp_path += "/";
    }
    acp_file_list.push_back(acp_path);
  }

  result->Create(acp_root, acp_file_list);
  return true;
}

bool CreateZipBuilder(const Path& zip, const ZipEntryPaths& entry_paths,
                      std::unique_ptr<devtools_ijar::ZipBuilder>* result) {
  const devtools_ijar::u8 estimated_size =
      devtools_ijar::ZipBuilder::EstimateSize(entry_paths.AbsPathPtrs(),
                                              entry_paths.EntryPathPtrs(),
                                              entry_paths.Size());

  if (estimated_size == 0) {
    LogError(__LINE__, "Failed to estimate zip size");
    return false;
  }

  std::string acp_zip;
  if (!WcsToAcp(zip.Get(), &acp_zip)) {
    LogErrorWithArg(__LINE__, "Failed to convert path", zip.Get());
    return false;
  }

  result->reset(
      devtools_ijar::ZipBuilder::Create(acp_zip.c_str(), estimated_size));
  if (result->get() == nullptr) {
    LogErrorWithValue(__LINE__, "Failed to create zip builder", errno);
    return false;
  }
  return true;
}

bool OpenFileForWriting(const Path& path, bazel::windows::AutoHandle* result) {
  HANDLE h = CreateFileW(AddUncPrefixMaybe(path).c_str(), GENERIC_WRITE,
                         FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
                         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError();
    LogErrorWithArgAndValue(__LINE__, "Failed to open file", path.Get(), err);
    return false;
  }
  *result = h;
  return true;
}

bool OpenExistingFileForRead(const Path& abs_path,
                             bazel::windows::AutoHandle* result) {
  HANDLE h = CreateFileW(AddUncPrefixMaybe(abs_path).c_str(), GENERIC_READ,
                         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError();
    LogErrorWithArgAndValue(__LINE__, "Failed to open file", abs_path.Get(),
                            err);
    return false;
  }
  *result = h;
  return true;
}

bool CreateEmptyFile(const Path& path) {
  bazel::windows::AutoHandle handle;
  return OpenFileForWriting(path, &handle);
}

bool ReadFromFile(HANDLE handle, uint8_t* dest, DWORD max_read) {
  if (max_read == 0) {
    return true;
  }

  DWORD total_read = 0;
  DWORD read = 0;
  do {
    if (!ReadFile(handle, dest + total_read, max_read - total_read, &read,
                  NULL)) {
      DWORD err = GetLastError();
      LogErrorWithValue(__LINE__, "Failed to read file", err);
      return false;
    }
    total_read += read;
  } while (read > 0 && total_read < max_read);
  return true;
}

bool ReadCompleteFile(const Path& path, std::unique_ptr<uint8_t[]>* data,
                      DWORD* size) {
  bazel::windows::AutoHandle handle;
  if (!OpenExistingFileForRead(path, &handle)) {
    LogError(__LINE__, path.Get());
    return false;
  }

  LARGE_INTEGER file_size;
  if (!GetFileSizeEx(handle, &file_size)) {
    DWORD err = GetLastError();
    LogErrorWithValue(__LINE__, path.Get(), err);
    return false;
  }

  // `ReadCompleteFile` doesn't support files larger than 4GB because most files
  // that this function will be reading (test outerr logs) are typically smaller
  // than that. (A buffered file reader would allow supporting larger files, but
  // that seems like overkill here.)
  if (file_size.QuadPart > 0xFFFFFFFF) {
    LogError(__LINE__, path.Get());
    return false;
  }
  const DWORD file_size_dw = file_size.QuadPart;
  *size = file_size_dw;

  // Allocate a buffer large enough to hold the whole file.
  data->reset(new uint8_t[file_size_dw]);
  if (!data->get()) {
    // Memory allocation failed.
    LogErrorWithValue(__LINE__, path.Get(), file_size_dw);
    return false;
  }

  return ReadFromFile(handle, data->get(), file_size_dw);
}

bool WriteToFile(HANDLE output, const void* buffer, const size_t size) {
  // Write `size` many bytes to the output file.
  DWORD total_written = 0;
  while (total_written < size) {
    DWORD written;
    if (!WriteFile(output, static_cast<const uint8_t*>(buffer) + total_written,
                   size - total_written, &written, NULL)) {
      DWORD err = GetLastError();
      LogErrorWithValue(__LINE__, "Failed to write file", err);
      return false;
    }
    total_written += written;
  }
  return true;
}

bool AppendFileTo(const Path& file, const size_t total_size, HANDLE output) {
  bazel::windows::AutoHandle input;
  if (!OpenExistingFileForRead(file, &input)) {
    LogErrorWithArg(__LINE__, "Failed to open file for reading", file.Get());
    return false;
  }

  const size_t buf_size = std::min<size_t>(total_size, /* 10 MB */ 10000000);
  std::unique_ptr<uint8_t[]> buffer(new uint8_t[buf_size]);

  while (true) {
    // Read at most `buf_size` many bytes from the input file.
    DWORD read = 0;
    if (!ReadFile(input, buffer.get(), buf_size, &read, NULL)) {
      DWORD err = GetLastError();
      LogErrorWithArgAndValue(__LINE__, "Failed to read file", file.Get(), err);
      return false;
    }
    if (read == 0) {
      // Reached end of input file.
      return true;
    }
    if (!WriteToFile(output, buffer.get(), read)) {
      LogErrorWithArg(__LINE__, "Failed to write contents from file",
                      file.Get());
      return false;
    }
  }
  return true;
}

// Returns the MIME type of the file name.
// If the MIME type is unknown or an error occurs, the method returns
// "application/octet-stream".
std::string GetMimeType(const std::string& filename) {
  static constexpr char* kDefaultMimeType = "application/octet-stream";
  std::string::size_type pos = filename.find_last_of('.');
  if (pos == std::string::npos) {
    return kDefaultMimeType;
  }
  char data[1000];
  DWORD data_size = 1000 * sizeof(char);
  if (RegGetValueA(HKEY_CLASSES_ROOT, filename.c_str() + pos, "Content Type",
                   RRF_RT_REG_SZ, NULL, data, &data_size) == ERROR_SUCCESS) {
    return data;
  }
  // The file extension is unknown, or it does not have a "Content Type" value,
  // or the value is too long. We don't care; just return the default.
  return kDefaultMimeType;
}

bool CreateUndeclaredOutputsManifestContent(const std::vector<FileInfo>& files,
                                            std::string* result) {
  std::stringstream stm;
  for (const auto& e : files) {
    if (!e.IsDirectory()) {
      // For each file, write a tab-separated line to the manifest with name
      // (relative to TEST_UNDECLARED_OUTPUTS_DIR), size, and mime type.
      // Example:
      //   foo.txt<TAB>9<TAB>text/plain
      //   bar/baz<TAB>2944<TAB>application/octet-stream
      std::string acp_path;
      if (!WcsToAcp(AsMixedPath(e.RelativePath()), &acp_path)) {
        return false;
      }

      stm << acp_path << "\t" << e.Size() << "\t" << GetMimeType(acp_path)
          << "\n";
    }
  }
  *result = stm.str();
  return true;
}

bool CreateUndeclaredOutputsManifest(const std::vector<FileInfo>& files,
                                     const Path& output) {
  std::string content;
  if (!CreateUndeclaredOutputsManifestContent(files, &content)) {
    LogErrorWithArg(__LINE__, "Failed to create manifest content for file",
                    output.Get());
    return false;
  }

  bazel::windows::AutoHandle handle;
  if (!OpenFileForWriting(output, &handle)) {
    LogErrorWithArg(__LINE__, "Failed to open file for writing", output.Get());
    return false;
  }

  if (!WriteToFile(handle, content.c_str(), content.size())) {
    LogErrorWithArg(__LINE__, "Failed to write file", output.Get());
    return false;
  }
  return true;
}

bool ExportXmlPath(const Path& cwd, Path* test_outerr, Path* xml_log) {
  if (!GetPathEnv(L"XML_OUTPUT_FILE", xml_log)) {
    LogError(__LINE__);
    return false;
  }
  xml_log->Absolutize(cwd);
  if (!test_outerr->Set(xml_log->Get() + L".log")) {
    LogError(__LINE__);
    return false;
  }
  std::wstring unix_result = AsMixedPath(xml_log->Get());
  return SetEnv(L"XML_OUTPUT_FILE", unix_result) &&
         // TODO(ulfjack): Update Gunit to accept XML_OUTPUT_FILE and drop the
         // GUNIT_OUTPUT env variable.
         SetEnv(L"GUNIT_OUTPUT", L"xml:" + unix_result) &&
         CreateDirectories(xml_log->Dirname()) && CreateEmptyFile(*test_outerr);
}

devtools_ijar::u4 GetZipAttr(const FileInfo& info) {
  // We use these hard-coded Unix permission masks because they are:
  // - stable, so the zip file is deterministic
  // - useful, because stat_to_zipattr expects a mode_t
  static constexpr mode_t kDirectoryMode = 040750;  // drwxr-x--- (directory)
  static constexpr mode_t kFileMode = 0100640;      // -rw-r----- (regular file)

  devtools_ijar::Stat file_stat;
  file_stat.total_size = info.Size();
  file_stat.is_directory = info.IsDirectory();
  file_stat.file_mode = info.IsDirectory() ? kDirectoryMode : kFileMode;
  return devtools_ijar::stat_to_zipattr(file_stat);
}

bool GetZipEntryPtr(devtools_ijar::ZipBuilder* zip_builder,
                    const char* entry_name, const devtools_ijar::u4 attr,
                    devtools_ijar::u1** result) {
  *result = zip_builder->NewFile(entry_name, attr);
  if (*result == nullptr) {
    LogErrorWithArg2(__LINE__, "Failed to add new zip entry for file",
                     entry_name, zip_builder->GetError());
    return false;
  }
  return true;
}

bool CreateZip(const Path& root, const std::vector<FileInfo>& files,
               const Path& abs_zip) {
  bool restore_oem_api = false;
  if (!AreFileApisANSI()) {
    // devtools_ijar::ZipBuilder uses the ANSI file APIs so we must set the
    // active code page to ANSI.
    SetFileApisToANSI();
    restore_oem_api = true;
  }
  Defer restore_file_apis([restore_oem_api]() {
    if (restore_oem_api) {
      SetFileApisToOEM();
    }
  });

  ZipEntryPaths zip_entry_paths;
  if (!ToZipEntryPaths(root, files, &zip_entry_paths)) {
    LogError(__LINE__, "Failed to create zip entry paths");
    return false;
  }

  std::unique_ptr<devtools_ijar::ZipBuilder> zip_builder;
  if (!CreateZipBuilder(abs_zip, zip_entry_paths, &zip_builder)) {
    LogError(__LINE__, "Failed to create zip builder");
    return false;
  }

  for (size_t i = 0; i < files.size(); ++i) {
    bazel::windows::AutoHandle handle;
    Path path;
    if (!path.Set(root.Get() + L"\\" + files[i].RelativePath()) ||
        (!files[i].IsDirectory() && !OpenExistingFileForRead(path, &handle))) {
      LogErrorWithArg(__LINE__, "Failed to open file for reading", path.Get());
      return false;
    }

    devtools_ijar::u1* dest;
    if (!GetZipEntryPtr(zip_builder.get(), zip_entry_paths.EntryPathPtrs()[i],
                        GetZipAttr(files[i]), &dest) ||
        (!files[i].IsDirectory() &&
         !ReadFromFile(handle, dest, files[i].Size()))) {
      LogErrorWithArg(__LINE__, "Failed to dump file into zip", path.Get());
      return false;
    }

    if (zip_builder->FinishFile(files[i].Size(), /* compress */ false,
                                /* compute_crc */ true) == -1) {
      LogErrorWithArg(__LINE__, "Failed to finish writing file to zip",
                      path.Get());
      return false;
    }
  }

  if (zip_builder->Finish() == -1) {
    LogErrorWithArg(__LINE__, "Failed to add file to zip",
                    zip_builder->GetError());
    return false;
  }

  return true;
}

bool GetAndUnexportUndeclaredOutputsEnvvars(const Path& cwd,
                                            UndeclaredOutputs* result) {
  // The test may only see TEST_UNDECLARED_OUTPUTS_DIR and
  // TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR, so keep those but unexport others.
  if (!GetPathEnv(L"TEST_UNDECLARED_OUTPUTS_ZIP", &(result->zip)) ||
      !UnsetEnv(L"TEST_UNDECLARED_OUTPUTS_ZIP") ||

      !GetPathEnv(L"TEST_UNDECLARED_OUTPUTS_MANIFEST", &(result->manifest)) ||
      !UnsetEnv(L"TEST_UNDECLARED_OUTPUTS_MANIFEST") ||

      !GetPathEnv(L"TEST_UNDECLARED_OUTPUTS_ANNOTATIONS",
                  &(result->annotations)) ||
      !UnsetEnv(L"TEST_UNDECLARED_OUTPUTS_ANNOTATIONS") ||

      !GetPathEnv(L"TEST_UNDECLARED_OUTPUTS_DIR", &(result->root)) ||

      !GetPathEnv(L"TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR",
                  &(result->annotations_dir))) {
    return false;
  }

  result->root.Absolutize(cwd);
  result->annotations_dir.Absolutize(cwd);
  result->zip.Absolutize(cwd);
  result->manifest.Absolutize(cwd);
  result->annotations.Absolutize(cwd);

  return SetPathEnv(L"TEST_UNDECLARED_OUTPUTS_DIR", result->root) &&
         SetPathEnv(L"TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR",
                    result->annotations_dir) &&
         CreateDirectories(result->root) &&
         CreateDirectories(result->annotations_dir);
}

bool PrintTestLogStartMarker() {
  std::wstring test_target;
  std::string acp_test_target;
  if (!GetEnv(L"TEST_TARGET", &test_target) ||
      !WcsToAcp(test_target, &acp_test_target)) {
    return false;
  }
  std::stringstream ss;
  if (test_target.empty()) {
    // According to the Bazel Test Encyclopedia, setting TEST_TARGET is
    // optional.
    ss << "Executing tests from unknown target\n";
  } else {
    ss << "Executing tests from " << acp_test_target << "\n";
  }

  // This header marks where --test_output=streamed will start being printed.
  ss << "---------------------------------------------------------------------"
        "--------\n";
  WriteStdout(ss.str());
  return true;
}

inline bool GetWorkspaceName(std::wstring* result) {
  return GetEnv(L"TEST_WORKSPACE", result) && !result->empty();
}

inline void ComputeRunfilePath(const std::wstring& test_workspace,
                               std::wstring* s) {
  if (s->size() >= 2 && (*s)[0] == L'.' && (*s)[1] == L'/') {
    s->erase(0, 2);
  }
  if (s->find(L"external/") == 0) {
    s->erase(0, 9);
  } else {
    *s = test_workspace + L"/" + *s;
  }
}

bool FindTestBinary(const Path& argv0, const Path& cwd, std::wstring test_path,
                    Path* result) {
  if (!blaze_util::IsAbsolute(test_path)) {
    std::string argv0_acp;
    if (!WcsToAcp(argv0.Get(), &argv0_acp)) {
      LogErrorWithArg(__LINE__, "Failed to convert path", argv0.Get());
      return false;
    }

    std::string error;
    std::unique_ptr<bazel::tools::cpp::runfiles::Runfiles> runfiles(
        bazel::tools::cpp::runfiles::Runfiles::Create(argv0_acp, &error));
    if (runfiles == nullptr) {
      LogError(__LINE__, "Failed to load runfiles");
      return false;
    }

    std::wstring workspace;
    if (!GetWorkspaceName(&workspace)) {
      LogError(__LINE__, "Failed to read %TEST_WORKSPACE%");
      return false;
    }

    ComputeRunfilePath(workspace, &test_path);

    std::string utf8_test_path;
    uint32_t err;
    if (!blaze_util::WcsToUtf8(test_path, &utf8_test_path, &err)) {
      LogErrorWithArgAndValue(__LINE__, "Failed to convert string to UTF-8",
                              test_path, err);
      return false;
    }

    std::string rloc = runfiles->Rlocation(utf8_test_path);
    if (!blaze_util::Utf8ToWcs(rloc, &test_path, &err)) {
      LogErrorWithArgAndValue(__LINE__, "Failed to convert string",
                              utf8_test_path, err);
    }
  }

  if (!result->Set(test_path)) {
    LogErrorWithArg(__LINE__, "Failed to set path", test_path);
    return false;
  }

  (void)result->Absolutize(cwd);
  return true;
}

bool CreateCommandLine(const Path& path, const std::wstring& args,
                       std::unique_ptr<WCHAR[]>* result) {
  // kMaxCmdline value: see lpCommandLine parameter of CreateProcessW.
  static constexpr size_t kMaxCmdline = 32767;

  if (path.Get().size() + args.size() > kMaxCmdline) {
    LogErrorWithValue(__LINE__, L"Command is too long",
                      path.Get().size() + args.size());
    return false;
  }

  // Add an extra character for the final null-terminator.
  result->reset(new WCHAR[path.Get().size() + args.size() + 1]);

  wcsncpy(result->get(), path.Get().c_str(), path.Get().size());
  wcsncpy(result->get() + path.Get().size(), args.c_str(), args.size() + 1);
  return true;
}

bool StartSubprocess(const Path& path, const std::wstring& args,
                     const Path& outerr, std::unique_ptr<Tee>* tee,
                     LARGE_INTEGER* start_time,
                     bazel::windows::WaitableProcess* process) {
  SECURITY_ATTRIBUTES inheritable_handle_sa = {sizeof(SECURITY_ATTRIBUTES),
                                               NULL, TRUE};

  // Create a pipe to stream the output of the subprocess to this process.
  // The subprocess inherits two copies of the writing end (one for stdout, one
  // for stderr). This process closes its copies of the handles.
  // This process keeps the reading end and streams data from the pipe to the
  // test log and to stdout.
  HANDLE pipe_read_h, pipe_write_h;
  if (!CreatePipe(&pipe_read_h, &pipe_write_h, &inheritable_handle_sa, 0)) {
    DWORD err = GetLastError();
    LogErrorWithValue(__LINE__, "CreatePipe", err);
    return false;
  }
  bazel::windows::AutoHandle pipe_read(pipe_read_h), pipe_write(pipe_write_h);

  // Duplicate the write end of the pipe.
  // The original will be connected to the stdout of the process, the duplicate
  // to stderr.
  HANDLE pipe_write_dup_h;
  if (!DuplicateHandle(GetCurrentProcess(), pipe_write, GetCurrentProcess(),
                       &pipe_write_dup_h, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
    DWORD err = GetLastError();
    LogErrorWithValue(__LINE__, "DuplicateHandle", err);
    return false;
  }
  bazel::windows::AutoHandle pipe_write_dup(pipe_write_dup_h);

  // Open a readonly handle to NUL. The subprocess inherits this handle that's
  // connected to its stdin.
  bazel::windows::AutoHandle devnull_read(CreateFileW(
      L"NUL", GENERIC_READ,
      FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
      &inheritable_handle_sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
  if (devnull_read == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError();
    LogErrorWithValue(__LINE__, "CreateFileW", err);
    return false;
  }

  // Open a handle to the test log file. The "tee" thread will write everything
  // into it that the subprocess writes to the pipe.
  bazel::windows::AutoHandle test_outerr;
  if (!OpenFileForWriting(outerr, &test_outerr)) {
    LogErrorWithArg(__LINE__, "Failed to open file for writing", outerr.Get());
    return false;
  }

  // Duplicate stdout's handle, and pass it to the tee thread, who will own it
  // and close it in the end.
  HANDLE stdout_dup_h;
  if (!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE),
                       GetCurrentProcess(), &stdout_dup_h, 0, FALSE,
                       DUPLICATE_SAME_ACCESS)) {
    DWORD err = GetLastError();
    LogErrorWithValue(__LINE__, "DuplicateHandle", err);
    return false;
  }
  bazel::windows::AutoHandle stdout_dup(stdout_dup_h);

  // Create the tee thread, and transfer ownerships of the `pipe_read`,
  // `test_outerr`, and `stdout_dup` handles.
  if (!TeeImpl::Create(&pipe_read, &test_outerr, &stdout_dup, tee)) {
    LogError(__LINE__);
    return false;
  }

  std::wstring werror;
  if (!process->Create(path.Get(), args, nullptr, L"", devnull_read, pipe_write,
                       pipe_write_dup, start_time, &werror)) {
    LogError(__LINE__, werror);
    return false;
  }
  return true;
}

bool ArchiveUndeclaredOutputs(const UndeclaredOutputs& undecl) {
  if (undecl.root.Get().empty()) {
    // TEST_UNDECLARED_OUTPUTS_DIR was undefined, there's nothing to archive.
    return true;
  }

  std::vector<FileInfo> files;
  return GetFileListRelativeTo(undecl.root, &files) &&
         (files.empty() ||
          (CreateZip(undecl.root, files, undecl.zip) &&
           CreateUndeclaredOutputsManifest(files, undecl.manifest)));
}

// Creates the Undeclared Outputs Annotations file.
//
// This file is a concatenation of every *.part file directly under
// `undecl_annot_dir`. The file is written to `output`.
bool CreateUndeclaredOutputsAnnotations(const Path& undecl_annot_dir,
                                        const Path& output) {
  if (undecl_annot_dir.Get().empty()) {
    // The directory's environment variable
    // (TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR) was probably undefined, nothing
    // to do.
    return true;
  }

  std::vector<FileInfo> files;
  if (!GetFileListRelativeTo(undecl_annot_dir, &files, 0)) {
    LogErrorWithArg(__LINE__, "Failed to get directory contents",
                    undecl_annot_dir.Get());
    return false;
  }
  // There are no *.part files under `undecl_annot_dir`, nothing to do.
  if (files.empty()) {
    return true;
  }

  bazel::windows::AutoHandle handle;
  if (!OpenFileForWriting(output, &handle)) {
    LogErrorWithArg(__LINE__, "Failed to open file for writing", output.Get());
    return false;
  }

  for (const auto& e : files) {
    if (!e.IsDirectory() &&
        e.RelativePath().rfind(L".part") == e.RelativePath().size() - 5) {
      // Only consume "*.part" files.
      Path path;
      if (!path.Set(undecl_annot_dir.Get() + L"\\" + e.RelativePath()) ||
          !AppendFileTo(path, e.Size(), handle)) {
        LogErrorWithArg2(__LINE__, "Failed to append file to another",
                         path.Get(), output.Get());
        return false;
      }
    }
  }
  return true;
}

bool ParseArgs(int argc, wchar_t** argv, Path* out_argv0,
               std::wstring* out_test_path_arg, std::wstring* out_args) {
  if (!out_argv0->Set(argv[0])) {
    return false;
  }
  argc--;
  argv++;

  if (argc < 1) {
    LogError(__LINE__, "Usage: $0 <test_path> [test_args...]");
    return false;
  }

  *out_test_path_arg = argv[0];
  std::wstringstream stm;
  for (int i = 1; i < argc; i++) {
    stm << L' ' << bazel::launcher::WindowsEscapeArg2(argv[i]);
  }
  *out_args = stm.str();
  return true;
}

bool ParseXmlWriterArgs(int argc, wchar_t** argv, const Path& cwd,
                        Path* out_test_log, Path* out_xml_log,
                        Duration* out_duration, int* out_exit_code) {
  if (argc < 5) {
    LogError(__LINE__,
             "Usage: $0 <test_output_path> <xml_log_path>"
             " <duration_in_seconds> <exit_code>");
    return false;
  }
  if (!out_test_log->Set(argv[1]) || out_test_log->Get().empty()) {
    LogErrorWithArg(__LINE__, "Failed to parse test log path argument",
                    argv[1]);
    return false;
  }
  out_test_log->Absolutize(cwd);
  if (!out_xml_log->Set(argv[2]) || out_xml_log->Get().empty()) {
    LogErrorWithArg(__LINE__, "Failed to parse XML log path argument", argv[2]);
    return false;
  }
  out_xml_log->Absolutize(cwd);
  if (!out_duration->FromString(argv[3])) {
    LogErrorWithArg(__LINE__, "Failed to parse test duration argument",
                    argv[3]);
    return false;
  }
  if (!ToInt(argv[4], out_exit_code)) {
    LogErrorWithArg(__LINE__, "Failed to parse exit code argument", argv[4]);
    return false;
  }
  return true;
}

bool TeeImpl::Create(bazel::windows::AutoHandle* input,
                     bazel::windows::AutoHandle* output1,
                     bazel::windows::AutoHandle* output2,
                     std::unique_ptr<Tee>* result) {
  std::unique_ptr<TeeImpl> tee(new TeeImpl(input, output1, output2));
  bazel::windows::AutoHandle thread(
      CreateThread(NULL, 0, ThreadFunc, tee.get(), 0, NULL));
  if (!thread.IsValid()) {
    return false;
  }
  result->reset(tee.release());
  return true;
}

DWORD WINAPI TeeImpl::ThreadFunc(LPVOID lpParam) {
  return reinterpret_cast<TeeImpl*>(lpParam)->MainFunc() ? 0 : 1;
}

bool TeeImpl::MainFunc() const {
  static constexpr size_t kBufferSize = 0x10000;
  DWORD read;
  uint8_t content[kBufferSize];
  while (ReadFile(input_, content, kBufferSize, &read, NULL)) {
    DWORD written;
    if (read > 0 && (!WriteFile(output1_, content, read, &written, NULL) ||
                     !WriteFile(output2_, content, read, &written, NULL))) {
      return false;
    }
  }
  return true;
}

int RunSubprocess(const Path& test_path, const std::wstring& args,
                  const Path& test_outerr, Duration* test_duration) {
  std::unique_ptr<Tee> tee;
  bazel::windows::WaitableProcess process;
  LARGE_INTEGER start, end, freq;
  if (!StartSubprocess(test_path, args, test_outerr, &tee, &start, &process)) {
    LogErrorWithArg(__LINE__, "Failed to start test process", test_path.Get());
    return 1;
  }

  std::wstring werror;
  int wait_res = process.WaitFor(-1, &end, &werror);
  if (wait_res != bazel::windows::WaitableProcess::kWaitSuccess) {
    LogErrorWithValue(__LINE__, werror, wait_res);
    return 1;
  }

  werror.clear();
  int result = process.GetExitCode(&werror);
  if (!werror.empty()) {
    LogError(__LINE__, werror);
    return 1;
  }

  QueryPerformanceFrequency(&freq);
  end.QuadPart -= start.QuadPart;
  decltype(LARGE_INTEGER::QuadPart) seconds;
  // Compute the number of seconds the test ran for.
  seconds = end.QuadPart / freq.QuadPart;
  // Check the remainder: if it's at least 0.5 seconds, round up.
  if ((end.QuadPart - seconds * freq.QuadPart) * 2 >= freq.QuadPart) {
    seconds += 1;
  }
  test_duration->seconds =
      (seconds > Duration::kMax) ? Duration::kMax : seconds;
  return result;
}

// Replace invalid XML characters and locate invalid CDATA sequences.
//
// The legal Unicode code points and ranges are U+0009, U+000A, U+000D,
// U+0020..U+D7FF, U+E000..U+FFFD, and U+10000..U+10FFFF.
//
// Assuming the input is UTF-8 encoded, that translates to the following
// regexps:
//   [\x9\xa\xd\x20-\x7f]                         <--- (9,A,D,20-7F)
//   [\xc0-\xdf][\x80-\xbf]                       <--- (0080-07FF)
//   [\xe0-\xec][\x80-\xbf][\x80-\xbf]            <--- (0800-CFFF)
//   [\xed][\x80-\x9f][\x80-\xbf]                 <--- (D000-D7FF)
//   [\xee][\x80-\xbf][\x80-\xbf]                 <--- (E000-EFFF)
//   [\xef][\x80-\xbe][\x80-\xbf]                 <--- (F000-FFEF)
//   [\xef][\xbf][\x80-\xbd]                      <--- (FFF0-FFFD)
//   [\xf0-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf] <--- (010000-10FFFF)
//
// (See https://github.com/bazelbuild/bazel/issues/4691#issuecomment-408089257)
//
// Every octet-sequence matching one of these regexps will be left alone, all
// other octet-sequences will be replaced by '?' characters.
bool CdataEscape(IFStream* in, std::basic_ostream<char>* out) {
  int c0 = in->Get();
  uint8_t p[3];
  for (; c0 < 256; c0 = in->Get()) {
    if (c0 == ']' && in->Peek(2, p) == 2 && p[0] == ']' && p[1] == '>') {
      *out << "]]>]]<![CDATA[>";
      if (!out->good()) {
        return false;
      }
      (void)in->Get();
      (void)in->Get();
    } else if (c0 == 0x9 || c0 == 0xA || c0 == 0xD ||
               (c0 >= 0x20 && c0 <= 0x7F)) {
      // Matched legal single-octet sequence.
      *out << (char)c0;
      if (!out->good()) {
        return false;
      }
    } else if (c0 >= 0xC0 && c0 <= 0xDF && in->Peek(1, p) == 1 &&
               p[0] >= 0x80 && p[0] <= 0xBF) {
      // Matched legal double-octet sequence. Skip the next octet.
      *out << (char)c0 << (char)p[0];
      if (!out->good()) {
        return false;
      }
      (void)in->Get();
    } else if (in->Peek(2, p) == 2 &&
               ((c0 >= 0xE0 && c0 <= 0xEC && p[0] >= 0x80 && p[0] <= 0xBF &&
                 p[1] >= 0x80 && p[1] <= 0xBF) ||
                (c0 == 0xED && p[0] >= 0x80 && p[0] <= 0x9F && p[1] >= 0x80 &&
                 p[1] <= 0xBF) ||
                (c0 == 0xEE && p[0] >= 0x80 && p[0] <= 0xBF && p[1] >= 0x80 &&
                 p[1] <= 0xBF) ||
                (c0 == 0xEF && p[0] >= 0x80 && p[0] <= 0xBE && p[1] >= 0x80 &&
                 p[1] <= 0xBF) ||
                (c0 == 0xEF && p[0] == 0xBF && p[1] >= 0x80 && p[1] <= 0xBD))) {
      // Matched legal triple-octet sequence. Skip the next two octets.
      *out << (char)c0 << (char)p[0] << (char)p[1];
      if (!out->good()) {
        return false;
      }
      (void)in->Get();
      (void)in->Get();
    } else if (in->Peek(3, p) == 3 && c0 >= 0xF0 && c0 <= 0xF7 &&
               p[0] >= 0x80 && p[0] <= 0xBF && p[1] >= 0x80 && p[1] <= 0xBF &&
               p[2] >= 0x80 && p[2] <= 0xBF) {
      // Matched legal quadruple-octet sequence. Skip the next three octets.
      *out << (char)c0 << (char)p[0] << (char)p[1] << (char)p[2];
      if (!out->good()) {
        return false;
      }
      (void)in->Get();
      (void)in->Get();
      (void)in->Get();
    } else {
      // Illegal octet; replace.
      *out << (char)'?';
      if (!out->good()) {
        return false;
      }
    }
  }
  return c0 == IFStream::kIFStreamErrorEOF;
}

bool GetTestName(std::wstring* result) {
  if (!GetEnv(L"TEST_BINARY", result) || result->empty()) {
    LogError(__LINE__, L"Failed to get test name");
    return false;
  }
  if (result->size() >= 2 && (*result)[0] == '.' && (*result)[1] == '/') {
    result->erase(0, 2);
  }

  // Ensure that test shards have unique names in the xml output, by including
  // the shard index in the test name.
  std::wstring total_shards_str;
  int total_shards = 0, shard_index = 0;
  if (!GetIntEnv(L"TEST_TOTAL_SHARDS", &total_shards_str, &total_shards)) {
    LogError(__LINE__);
    return false;
  }
  if (total_shards > 0) {
    std::wstring shard_index_str;
    if (!GetIntEnv(L"TEST_SHARD_INDEX", &shard_index_str, &shard_index) ||
        shard_index_str.empty()) {
      LogError(__LINE__);
      return false;
    }
    std::wstringstream stm;
    stm << *result << L"_shard_" << (shard_index + 1) << L"/"
        << total_shards_str;
    *result = stm.str();
  }

  return true;
}

std::string CreateErrorTag(int exit_code) {
  if (exit_code != 0) {
    std::stringstream ss;
    ss << "<error message=\"exited with error code " << exit_code
       << "\"></error>";
    return ss.str();
  } else {
    return std::string();
  }
}

bool ShouldCreateXml(const Path& xml_log, bool* result) {
  *result = true;

  DWORD attr = GetFileAttributesW(AddUncPrefixMaybe(xml_log).c_str());
  if (attr != INVALID_FILE_ATTRIBUTES) {
    // The XML file already exists, maybe the test framework wrote it.
    // Leave the file alone.
    *result = false;
    return true;
  }

  std::wstring split_xml_generation;
  if (!GetEnv(L"EXPERIMENTAL_SPLIT_XML_GENERATION", &split_xml_generation)) {
    LogError(__LINE__, "Failed to get %EXPERIMENTAL_SPLIT_XML_GENERATION%");
    return false;
  }
  if (split_xml_generation == L"1") {
    // Bazel generates the test xml as a separate action, so we don't have to
    // create it.
    *result = false;
  }

  return true;
}

bool CreateXmlLog(const Path& output, const Path& test_outerr,
                  const Duration duration, const int exit_code,
                  const bool delete_afterwards) {
  bool should_create_xml;
  if (!ShouldCreateXml(output, &should_create_xml)) {
    LogErrorWithArg(__LINE__, "Failed to decide if XML log is needed",
                    output.Get());
    return false;
  }
  if (!should_create_xml) {
    return true;
  }

  Defer delete_test_outerr([test_outerr, delete_afterwards]() {
    // Delete the test's outerr file after we have the XML file.
    // We don't care if this succeeds or not, because the outerr file is not a
    // declared output.
    if (delete_afterwards) {
      DeleteFileW(test_outerr.Get().c_str());
    }
  });

  std::wstring test_name;
  int errors = (exit_code == 0) ? 0 : 1;
  std::string error_msg = CreateErrorTag(exit_code);
  if (!GetTestName(&test_name)) {
    LogError(__LINE__);
    return false;
  }

  std::string acp_test_name;
  if (!WcsToAcp(test_name, &acp_test_name)) {
    LogError(__LINE__, test_name.c_str());
    return false;
  }

  bazel::windows::AutoHandle test_log;
  if (!OpenExistingFileForRead(test_outerr, &test_log)) {
    LogError(__LINE__, test_outerr.Get().c_str());
    return false;
  }

  std::unique_ptr<IFStream> istm(IFStreamImpl::Create(test_log));
  if (istm == nullptr) {
    LogError(__LINE__, test_outerr.Get().c_str());
    return false;
  }

  std::ofstream ostm(
      AddUncPrefixMaybe(output).c_str(),
      std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
  if (!ostm.is_open() || !ostm.good()) {
    LogError(__LINE__, output.Get().c_str());
    return false;
  }

  // Create XML file stub.
  ostm << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
          "<testsuites>\n"
          "<testsuite name=\""
       << acp_test_name << "\" tests=\"1\" failures=\"0\" errors=\"" << errors
       << "\">\n"
          "<testcase name=\""
       << acp_test_name << "\" status=\"run\" duration=\"" << duration.seconds
       << "\" time=\"" << duration.seconds << "\">" << error_msg
       << "</testcase>\n"
          "<system-out><![CDATA[";
  if (!ostm.good()) {
    LogError(__LINE__, output.Get().c_str());
    return false;
  }

  // Encode test log to make it embeddable in CDATA.
  if (!CdataEscape(istm.get(), &ostm)) {
    LogError(__LINE__, output.Get().c_str());
    return false;
  }

  // Append CDATA end and closing tags.
  ostm << "]]></system-out>\n</testsuite>\n</testsuites>\n";
  if (!ostm.good()) {
    LogError(__LINE__, output.Get().c_str());
    return false;
  }
  return true;
}

bool Duration::FromString(const wchar_t* str) {
  int result;
  if (!ToInt(str, &result)) {
    LogErrorWithArg(__LINE__, "Failed to parse int from string", str);
    return false;
  }
  this->seconds = result;
  return true;
}

bool Path::Set(const std::wstring& path) {
  std::wstring result;
  std::string error;
  if (!blaze_util::AsWindowsPath(path, &result, &error)) {
    LogError(__LINE__, error);
    return false;
  }
  path_ = result;
  return true;
}

bool Path::Absolutize(const Path& cwd) {
  if (!path_.empty() && !blaze_util::IsAbsolute(path_)) {
    // Both paths are normalized, but this->path_ may begin with ".."s so we
    // must normalize after joining.
    // We wouldn't need full normalization, just normlize at the joined edges,
    // but let's keep the code simple and normalize fully. (AsWindowsPath in
    // Set normalizes.)
    return Set(cwd.path_ + L"\\" + path_);
  } else {
    return false;
  }
}

Path Path::Dirname() const {
  Path result;
  result.path_ = blaze_util::SplitPathW(path_).first;
  return result;
}

IFStream* IFStreamImpl::Create(HANDLE handle, DWORD page_size) {
  std::unique_ptr<uint8_t[]> data(new uint8_t[page_size * 2]);
  DWORD read;
  if (!ReadFile(handle, data.get(), page_size * 2, &read, NULL)) {
    DWORD err = GetLastError();
    if (err == ERROR_BROKEN_PIPE) {
      read = 0;
    } else {
      LogErrorWithValue(__LINE__, "Failed to read from file", err);
      return nullptr;
    }
  }
  return new IFStreamImpl(handle, std::move(data), read, page_size);
}

int IFStreamImpl::Get() {
  if (pos_ == end_) {
    return kIFStreamErrorEOF;
  }

  int result = pages_[pos_];
  if (pos_ + 1 < end_) {
    pos_++;
    return result;
  }

  // Overwrite the *active* page: we are about to move off of it.
  DWORD offs = (pos_ < page_size_) ? 0 : page_size_;
  DWORD read;
  if (!ReadFile(handle_, pages_.get() + offs, page_size_, &read, NULL)) {
    DWORD err = GetLastError();
    if (err == ERROR_BROKEN_PIPE) {
      // The stream is reading from a pipe, and there's no more data.
    } else {
      LogErrorWithValue(__LINE__, "Failed to read from file", err);
      return kIFStreamErrorIO;
    }
  }
  pos_ = (pos_ < page_size_) ? page_size_ : 0;
  end_ = pos_ + next_size_;
  next_size_ = read;
  return result;
}

DWORD IFStreamImpl::Peek(DWORD n, uint8_t* out) const {
  if (pos_ == end_) {
    return 0;
  }

  DWORD n1 = end_ - pos_;
  if (n1 > n) {
    n1 = n;  // all 'n' bytes are on the current page
  }
  memcpy(out, pages_.get() + pos_, n1);
  if (n1 == n) {
    return n;
  }

  DWORD offs = (pos_ < page_size_) ? page_size_ : 0;
  DWORD n2 = n - n1;  // how much is left to read
  if (n2 > next_size_) {
    n2 = next_size_;  // read no more than the other page's size
  }
  memcpy(out + n1, pages_.get() + offs, n2);
  return n1 + n2;
}

}  // namespace

void ZipEntryPaths::Create(const std::string& root,
                           const std::vector<std::string>& relative_paths) {
  size_ = relative_paths.size();

  size_t total_size = 0;
  for (const auto& e : relative_paths) {
    // Increase total size for absolute paths by <root> + "/" + <path> +
    // null-terminator.
    total_size += root.size() + 1 + e.size() + 1;
  }

  // Store all absolute paths in one continuous char array.
  abs_paths_.reset(new char[total_size]);

  // Store pointers in two arrays. The pointers point into `abs_path`.
  // We'll pass these paths to devtools_ijar::ZipBuilder::EstimateSize that
  // expects an array of char pointers. The last element must be NULL, so
  // allocate one extra pointer.
  abs_path_ptrs_.reset(new char*[relative_paths.size() + 1]);
  entry_path_ptrs_.reset(new char*[relative_paths.size() + 1]);

  char* p = abs_paths_.get();
  // Create all full paths (root + '/' + relative_paths[i] + '\0').
  //
  // If `root` is "c:/foo", then store the following:
  //
  // - Store each absolute path consecutively in `abs_paths_` (via `p`).
  //   Store paths with forward slashes and not backslashes, because we use them
  //   as zip entry paths, as well as paths we open with CreateFileA (which can
  //   convert these paths internally to Windows-style).
  //   Example: "c:/foo/bar.txt\0c:/foo/sub/baz.txt\0"
  //
  // - Store pointers in `abs_path_ptrs_`, pointing to the start of each
  //   string inside `abs_paths_`.
  //   Example: "c:/foo/bar.txt\0c:/foo/sub/baz.txt\0"
  //             ^ here          ^ here
  //
  // - Store pointers in `entry_path_ptrs_`, pointing to the start of each
  //   zip entry path inside `abs_paths_`, which is the part of each path
  //   that's relative to `root`.
  //   Example: "c:/foo/bar.txt\0c:/foo/sub/baz.txt\0"
  //                    ^ here          ^ here
  //
  // - Because the ZipBuilder requires that the file paths and zip entry paths
  //   are null-terminated arrays, we insert an extra null at their ends.
  for (size_t i = 0; i < relative_paths.size(); ++i) {
    abs_path_ptrs_.get()[i] = p;
    strncpy(p, root.c_str(), root.size());
    p += root.size();
    *p++ = '/';
    entry_path_ptrs_.get()[i] = p;
    strncpy(p, relative_paths[i].c_str(), relative_paths[i].size() + 1);
    p += relative_paths[i].size() + 1;
  }
  abs_path_ptrs_.get()[relative_paths.size()] = nullptr;
  entry_path_ptrs_.get()[relative_paths.size()] = nullptr;
}

int TestWrapperMain(int argc, wchar_t** argv) {
  Path argv0;
  std::wstring test_path_arg;
  Path test_path, exec_root, srcdir, tmpdir, test_outerr, xml_log;
  UndeclaredOutputs undecl;
  std::wstring args;
  if (!ParseArgs(argc, argv, &argv0, &test_path_arg, &args) ||
      !PrintTestLogStartMarker() || !GetCwd(&exec_root) ||
      !FindTestBinary(argv0, exec_root, test_path_arg, &test_path) ||
      !ExportUserName() || !ExportSrcPath(exec_root, &srcdir) ||
      !ExportTmpPath(exec_root, &tmpdir) || !ExportHome(tmpdir) ||
      !ExportRunfiles(exec_root, srcdir) || !ExportShardStatusFile(exec_root) ||
      !ExportGtestVariables(tmpdir) || !ExportMiscEnvvars(exec_root) ||
      !ExportXmlPath(exec_root, &test_outerr, &xml_log) ||
      !GetAndUnexportUndeclaredOutputsEnvvars(exec_root, &undecl)) {
    return 1;
  }

  Duration test_duration;
  int result = RunSubprocess(test_path, args, test_outerr, &test_duration);
  if (!CreateXmlLog(xml_log, test_outerr, test_duration, result, true) ||
      !ArchiveUndeclaredOutputs(undecl) ||
      !CreateUndeclaredOutputsAnnotations(undecl.annotations_dir,
                                          undecl.annotations)) {
    return 1;
  }
  return result;
}

int XmlWriterMain(int argc, wchar_t** argv) {
  Path cwd, test_outerr, test_xml_log;
  Duration duration;
  int exit_code = 0;

  if (!GetCwd(&cwd) ||
      !ParseXmlWriterArgs(argc, argv, cwd, &test_outerr, &test_xml_log,
                          &duration, &exit_code) ||
      !CreateXmlLog(test_xml_log, test_outerr, duration, exit_code, false)) {
    return 1;
  }

  return 0;
}

namespace testing {

bool TestOnly_GetEnv(const wchar_t* name, std::wstring* result) {
  return GetEnv(name, result);
}

bool TestOnly_GetFileListRelativeTo(const std::wstring& abs_root,
                                    std::vector<FileInfo>* result,
                                    int depth_limit) {
  Path root;
  return blaze_util::IsAbsolute(abs_root) && root.Set(abs_root) &&
         GetFileListRelativeTo(root, result, depth_limit);
}

bool TestOnly_ToZipEntryPaths(const std::wstring& abs_root,
                              const std::vector<FileInfo>& files,
                              ZipEntryPaths* result) {
  Path root;
  return blaze_util::IsAbsolute(abs_root) && root.Set(abs_root) &&
         ToZipEntryPaths(root, files, result);
}

bool TestOnly_CreateZip(const std::wstring& abs_root,
                        const std::vector<FileInfo>& files,
                        const std::wstring& abs_zip) {
  Path root, zip;
  return blaze_util::IsAbsolute(abs_root) && root.Set(abs_root) &&
         blaze_util::IsAbsolute(abs_zip) && zip.Set(abs_zip) &&
         CreateZip(root, files, zip);
}

std::string TestOnly_GetMimeType(const std::string& filename) {
  return GetMimeType(filename);
}

bool TestOnly_CreateUndeclaredOutputsManifest(
    const std::vector<FileInfo>& files, std::string* result) {
  return CreateUndeclaredOutputsManifestContent(files, result);
}

bool TestOnly_CreateUndeclaredOutputsAnnotations(
    const std::wstring& abs_root, const std::wstring& abs_output) {
  Path root, output;
  return blaze_util::IsAbsolute(abs_root) && root.Set(abs_root) &&
         blaze_util::IsAbsolute(abs_output) && output.Set(abs_output) &&
         CreateUndeclaredOutputsAnnotations(root, output);
}

bool TestOnly_AsMixedPath(const std::wstring& path, std::string* result) {
  Path p;
  return p.Set(path) && WcsToAcp(AsMixedPath(RemoveUncPrefixMaybe(p)), result);
}

bool TestOnly_CreateTee(bazel::windows::AutoHandle* input,
                        bazel::windows::AutoHandle* output1,
                        bazel::windows::AutoHandle* output2,
                        std::unique_ptr<Tee>* result) {
  return TeeImpl::Create(input, output1, output2, result);
}

bool TestOnly_CdataEncode(IFStream* in_stm, std::basic_ostream<char>* out_stm) {
  return CdataEscape(in_stm, out_stm);
}

IFStream* TestOnly_CreateIFStream(HANDLE handle, DWORD page_size) {
  return IFStreamImpl::Create(handle, page_size);
}

}  // namespace testing
}  // namespace test_wrapper
}  // namespace tools
}  // namespace bazel
