// Copyright 2014 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.

#include "src/main/cpp/blaze_util_platform.h"

#include <fcntl.h>
#include <stdarg.h>  // va_start, va_end, va_list

#include <windows.h>
#include <lmcons.h>          // UNLEN
#include <versionhelpers.h>  // IsWindows8OrGreater

#include <io.h>            // _open
#include <knownfolders.h>  // FOLDERID_Profile
#include <objbase.h>       // CoTaskMemFree
#include <shlobj.h>        // SHGetKnownFolderPath

#include <algorithm>
#include <atomic>
#include <cstdio>
#include <cstdlib>
#include <mutex>  // NOLINT
#include <set>
#include <sstream>
#include <thread>       // NOLINT (to silence Google-internal linter)
#include <type_traits>  // static_assert
#include <vector>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/global_variables.h"
#include "src/main/cpp/startup_options.h"
#include "src/main/cpp/util/errors.h"
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/file_platform.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/md5.h"
#include "src/main/cpp/util/numbers.h"
#include "src/main/cpp/util/path.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/util.h"

namespace blaze {

// Ensure we can safely cast (const) wchar_t* to LP(C)WSTR.
// This is true with MSVC but usually not with GCC.
static_assert(sizeof(wchar_t) == sizeof(WCHAR),
              "wchar_t and WCHAR should be the same size");

// When using widechar Win32 API functions the maximum path length is 32K.
// Add 4 characters for potential UNC prefix and a couple more for safety.
static const size_t kWindowsPathBufferSize = 0x8010;

using bazel::windows::AutoAttributeList;
using bazel::windows::AutoHandle;
using bazel::windows::CreateJunction;
using bazel::windows::CreateJunctionResult;

// TODO(bazel-team): stop using BAZEL_DIE, handle errors on the caller side.
// BAZEL_DIE calls exit(exitcode), which makes it difficult to follow the
// control flow and does not call destructors on local variables on the call
// stack.
using blaze_util::GetLastErrorString;

using std::string;
using std::unique_ptr;
using std::wstring;

namespace embedded_binaries {

class WindowsDumper : public Dumper {
 public:
  static WindowsDumper* Create(string* error);
  ~WindowsDumper() { Finish(nullptr); }
  void Dump(const void* data, const size_t size, const string& path) override;
  bool Finish(string* error) override;

 private:
  WindowsDumper()
      : threadpool_(NULL), cleanup_group_(NULL), was_error_(false) {}

  PTP_POOL threadpool_;
  PTP_CLEANUP_GROUP cleanup_group_;
  TP_CALLBACK_ENVIRON threadpool_env_;
  std::mutex dir_cache_lock_;
  std::set<string> dir_cache_;
  std::atomic_bool was_error_;
  string error_msg_;
};

namespace {

class DumpContext {
 public:
  DumpContext(unique_ptr<uint8_t[]> data, const size_t size, const string path,
              std::mutex* dir_cache_lock, std::set<string>* dir_cache,
              std::atomic_bool* was_error, string* error_msg);
  void Run();

 private:
  void MaybeSignalError(const string& msg);

  unique_ptr<uint8_t[]> data_;
  const size_t size_;
  const string path_;
  std::mutex* dir_cache_lock_;
  std::set<string>* dir_cache_;
  std::atomic_bool* was_error_;
  string* error_msg_;
};

VOID CALLBACK WorkCallback(_Inout_ PTP_CALLBACK_INSTANCE Instance,
                           _Inout_opt_ PVOID Context, _Inout_ PTP_WORK Work);

}  // namespace

Dumper* Create(string* error) { return WindowsDumper::Create(error); }

WindowsDumper* WindowsDumper::Create(string* error) {
  unique_ptr<WindowsDumper> result(new WindowsDumper());

  result->threadpool_ = CreateThreadpool(NULL);
  if (result->threadpool_ == NULL) {
    if (error) {
      string msg = GetLastErrorString();
      *error = "CreateThreadpool failed: " + msg;
    }
    return nullptr;
  }

  result->cleanup_group_ = CreateThreadpoolCleanupGroup();
  if (result->cleanup_group_ == NULL) {
    string msg = GetLastErrorString();
    CloseThreadpool(result->threadpool_);
    if (error) {
      string msg = GetLastErrorString();
      *error = "CreateThreadpoolCleanupGroup failed: " + msg;
    }
    return nullptr;
  }

  // I (@laszlocsomor) experimented with different thread counts and found that
  // 8 threads provide a significant advantage over 1 thread, but adding more
  // threads provides only marginal speedup.
  SetThreadpoolThreadMaximum(result->threadpool_, 16);
  SetThreadpoolThreadMinimum(result->threadpool_, 8);

  InitializeThreadpoolEnvironment(&result->threadpool_env_);
  SetThreadpoolCallbackPool(&result->threadpool_env_, result->threadpool_);
  SetThreadpoolCallbackCleanupGroup(&result->threadpool_env_,
                                    result->cleanup_group_, NULL);

  return result.release();  // release pointer ownership
}

void WindowsDumper::Dump(const void* data, const size_t size,
                         const string& path) {
  if (was_error_) {
    return;
  }

  unique_ptr<uint8_t[]> data_copy(new uint8_t[size]);
  memcpy(data_copy.get(), data, size);
  unique_ptr<DumpContext> ctx(new DumpContext(std::move(data_copy), size, path,
                                              &dir_cache_lock_, &dir_cache_,
                                              &was_error_, &error_msg_));
  PTP_WORK w = CreateThreadpoolWork(WorkCallback, ctx.get(), &threadpool_env_);
  if (w == NULL) {
    string err = GetLastErrorString();
    if (!was_error_.exchange(true)) {
      // Benign race condition: though we use no locks to access `error_msg_`,
      // only one thread may ever flip `was_error_` from false to true and enter
      // the body of this if-clause. Since `was_error_` is the same object as
      // used by all other threads trying to write to `error_msg_` (see
      // DumpContext::MaybeSignalError), using it provides adequate mutual
      // exclusion to write `error_msg_`.
      error_msg_ = string("WindowsDumper::Dump() couldn't submit work: ") + err;
    }
  } else {
    ctx.release();  // release pointer ownership
    SubmitThreadpoolWork(w);
  }
}

bool WindowsDumper::Finish(string* error) {
  if (threadpool_ == NULL) {
    return true;
  }
  CloseThreadpoolCleanupGroupMembers(cleanup_group_, FALSE, NULL);
  CloseThreadpoolCleanupGroup(cleanup_group_);
  CloseThreadpool(threadpool_);
  threadpool_ = NULL;
  cleanup_group_ = NULL;
  if (was_error_ && error) {
    // No race condition reading `error_msg_`: all worker threads terminated
    // by now.
    *error = error_msg_;
  }
  return !was_error_;
}

namespace {

DumpContext::DumpContext(unique_ptr<uint8_t[]> data, const size_t size,
                         const string path, std::mutex* dir_cache_lock,
                         std::set<string>* dir_cache,
                         std::atomic_bool* was_error, string* error_msg)
    : data_(std::move(data)),
      size_(size),
      path_(path),
      dir_cache_lock_(dir_cache_lock),
      dir_cache_(dir_cache),
      was_error_(was_error),
      error_msg_(error_msg) {}

void DumpContext::Run() {
  string dirname = blaze_util::Dirname(path_);

  bool success = true;
  // Performance optimization: memoize the paths we already created a
  // directory for, to spare a stat in attempting to recreate an already
  // existing directory. This optimization alone shaves off seconds from the
  // extraction time on Windows.
  {
    std::lock_guard<std::mutex> guard(*dir_cache_lock_);
    if (dir_cache_->insert(dirname).second) {
      success = blaze_util::MakeDirectories(dirname, 0777);
    }
  }

  if (!success) {
    MaybeSignalError(string("Couldn't create directory '") + dirname + "'");
    return;
  }

  if (!blaze_util::WriteFile(data_.get(), size_, path_, 0755)) {
    MaybeSignalError(string("Failed to write zipped file '") + path_ + "'");
  }
}

void DumpContext::MaybeSignalError(const string& msg) {
  if (!was_error_->exchange(true)) {
    // Benign race condition: though we use no locks to access `error_msg_`,
    // only one thread may ever flip `was_error_` from false to true and enter
    // the body of this if-clause. Since `was_error_` is the same object as used
    // by all other threads and by WindowsDumper::Dump(), using it provides
    // adequate mutual exclusion to write `error_msg_`.
    *error_msg_ = msg;
  }
}

VOID CALLBACK WorkCallback(_Inout_ PTP_CALLBACK_INSTANCE Instance,
                           _Inout_opt_ PVOID Context, _Inout_ PTP_WORK Work) {
  unique_ptr<DumpContext> ctx(reinterpret_cast<DumpContext*>(Context));
  ctx->Run();
}

}  // namespace

}  // namespace embedded_binaries

SignalHandler SignalHandler::INSTANCE;

class WindowsClock {
 public:
  uint64_t GetMilliseconds() const;

  static const WindowsClock INSTANCE;

 private:
  // Clock frequency per seconds.
  // It's safe to cache this because (from QueryPerformanceFrequency on MSDN):
  // "The frequency of the performance counter is fixed at system boot and is
  // consistent across all processors. Therefore, the frequency need only be
  // queried upon application initialization, and the result can be cached."
  const LARGE_INTEGER kFrequency;

  WindowsClock();

  static LARGE_INTEGER GetFrequency();
  static LARGE_INTEGER GetMillisecondsAsLargeInt(const LARGE_INTEGER& freq);
};

BOOL WINAPI ConsoleCtrlHandler(_In_ DWORD ctrlType) {
  static volatile int sigint_count = 0;
  switch (ctrlType) {
    case CTRL_C_EVENT:
    case CTRL_BREAK_EVENT:
      if (++sigint_count >= 3) {
        SigPrintf(
            "\n%s caught third Ctrl+C handler signal; killed.\n\n",
            SignalHandler::Get().GetGlobals()->options->product_name.c_str());
        if (SignalHandler::Get().GetGlobals()->server_pid != -1) {
          KillServerProcess(
              SignalHandler::Get().GetGlobals()->server_pid,
              SignalHandler::Get().GetGlobals()->options->output_base);
        }
        _exit(1);
      }
      SigPrintf(
          "\n%s Ctrl+C handler; shutting down.\n\n",
          SignalHandler::Get().GetGlobals()->options->product_name.c_str());
      SignalHandler::Get().CancelServer();
      return TRUE;

    case CTRL_CLOSE_EVENT:
      SignalHandler::Get().CancelServer();
      return TRUE;
  }
  return false;
}

void SignalHandler::Install(GlobalVariables* globals,
                            SignalHandler::Callback cancel_server) {
  _globals = globals;
  _cancel_server = cancel_server;
  ::SetConsoleCtrlHandler(&ConsoleCtrlHandler, TRUE);
}

ATTRIBUTE_NORETURN void SignalHandler::PropagateSignalOrExit(int exit_code) {
  // We do not handle signals on Windows; always exit with exit_code.
  exit(exit_code);
}



// A signal-safe version of fprintf(stderr, ...).
//
// WARNING: any output from the blaze client may be interleaved
// with output from the blaze server.  In --curses mode,
// the Blaze server often erases the previous line of output.
// So, be sure to end each such message with TWO newlines,
// otherwise it may be erased by the next message from the
// Blaze server.
// Also, it's a good idea to start each message with a newline,
// in case the Blaze server has written a partial line.
void SigPrintf(const char *format, ...) {
  int stderr_fileno = _fileno(stderr);
  char buf[1024];
  va_list ap;
  va_start(ap, format);
  int r = vsnprintf(buf, sizeof buf, format, ap);
  va_end(ap);
  if (write(stderr_fileno, buf, r) <= 0) {
    // We don't care, just placate the compiler.
  }
}

static void PrintErrorW(const wstring& op) {
  DWORD last_error = ::GetLastError();
  if (last_error == 0) {
    return;
  }

  WCHAR* message_buffer;
  FormatMessageW(
      /* dwFlags */ FORMAT_MESSAGE_ALLOCATE_BUFFER |
          FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
      /* lpSource */ nullptr,
      /* dwMessageId */ last_error,
      /* dwLanguageId */ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      /* lpBuffer */ message_buffer,
      /* nSize */ 0,
      /* Arguments */ nullptr);

  fwprintf(stderr, L"ERROR: %s: %s (%d)\n", op.c_str(), message_buffer,
           last_error);
  LocalFree(message_buffer);
}

void WarnFilesystemType(const string& output_base) {
}

string GetProcessIdAsString() {
  return ToString(GetCurrentProcessId());
}

string GetSelfPath() {
  WCHAR buffer[kWindowsPathBufferSize] = {0};
  if (!GetModuleFileNameW(0, buffer, kWindowsPathBufferSize)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "GetSelfPath: GetModuleFileNameW: " << GetLastErrorString();
  }
  return string(blaze_util::WstringToCstring(buffer).get());
}

string GetOutputRoot() {
  string home = GetHomeDir();
  if (home.empty()) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "Cannot find a good output root. Use the --output_user_root flag.";
  }
  return home;
}

string GetHomeDir() {
  PWSTR wpath;
  if (SUCCEEDED(::SHGetKnownFolderPath(FOLDERID_Profile, KF_FLAG_DEFAULT, NULL,
                                       &wpath))) {
    string result = string(blaze_util::WstringToCstring(wpath).get());
    ::CoTaskMemFree(wpath);
    return result;
  }
  return GetEnv("HOME");  // only defined in MSYS/Cygwin
}

string FindSystemWideBlazerc() {
  // TODO(bazel-team): figure out a good path to return here.
  return "";
}

string GetJavaBinaryUnderJavabase() { return "bin/java.exe"; }

uint64_t GetMillisecondsMonotonic() {
  return WindowsClock::INSTANCE.GetMilliseconds();
}

void SetScheduling(bool batch_cpu_scheduling, int io_nice_level) {
  // TODO(bazel-team): There should be a similar function on Windows.
}

string GetProcessCWD(int pid) {
  // TODO(bazel-team) 2016-11-18: decide whether we need this on Windows and
  // implement or delete.
  return "";
}

bool IsSharedLibrary(const string &filename) {
  return blaze_util::ends_with(filename, ".dll");
}

string GetSystemJavabase() {
  string javahome(GetEnv("JAVA_HOME"));
  if (javahome.empty()) {
    return "";
  }
  return javahome;
}

namespace {

// Max command line length is per CreateProcess documentation
// (https://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx)
//
// Quoting rules are described here:
// https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/

static const int MAX_CMDLINE_LENGTH = 32768;

struct CmdLine {
  char cmdline[MAX_CMDLINE_LENGTH];
};
static void CreateCommandLine(CmdLine* result, const string& exe,
                              const std::vector<string>& args_vector) {
  std::ostringstream cmdline;
  string short_exe;
  string error;
  if (!blaze_util::AsShortWindowsPath(exe, &short_exe, &error)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "CreateCommandLine: AsShortWindowsPath(" << exe << "): " << error;
  }
  bool first = true;
  for (const auto& s : args_vector) {
    if (first) {
      first = false;
      // Skip first argument, instead use quoted executable name.
      cmdline << '\"' << short_exe << '\"';
      continue;
    } else {
      cmdline << ' ';
    }

    bool has_space = s.find(" ") != string::npos;

    if (has_space) {
      cmdline << '\"';
    }

    std::string::const_iterator it = s.begin();
    while (it != s.end()) {
      char ch = *it++;
      switch (ch) {
        case '"':
          // Escape double quotes
          cmdline << "\\\"";
          break;

        case '\\':
          if (it == s.end()) {
            // Backslashes at the end of the string are quoted if we add quotes
            cmdline << (has_space ? "\\\\" : "\\");
          } else {
            // Backslashes everywhere else are quoted if they are followed by a
            // quote or a backslash
            cmdline << (*it == '"' || *it == '\\' ? "\\\\" : "\\");
          }
          break;

        default:
          cmdline << ch;
      }
    }

    if (has_space) {
      cmdline << '\"';
    }
  }

  string cmdline_str = cmdline.str();
  if (cmdline_str.size() >= MAX_CMDLINE_LENGTH) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "Command line too long (" << cmdline_str.size() << " > "
        << MAX_CMDLINE_LENGTH << "): " << cmdline_str;
  }

  // Copy command line into a mutable buffer.
  // CreateProcess is allowed to mutate its command line argument.
  strncpy(result->cmdline, cmdline_str.c_str(), MAX_CMDLINE_LENGTH - 1);
  result->cmdline[MAX_CMDLINE_LENGTH - 1] = 0;
}

}  // namespace

static bool GetProcessStartupTime(HANDLE process, uint64_t* result) {
  FILETIME creation_time, dummy1, dummy2, dummy3;
  // GetProcessTimes cannot handle NULL arguments.
  if (process == INVALID_HANDLE_VALUE ||
      !::GetProcessTimes(process, &creation_time, &dummy1, &dummy2, &dummy3)) {
    return false;
  }
  *result = static_cast<uint64_t>(creation_time.dwHighDateTime) << 32 |
            creation_time.dwLowDateTime;
  return true;
}

static void WriteProcessStartupTime(const string& server_dir, HANDLE process) {
  uint64_t start_time = 0;
  if (!GetProcessStartupTime(process, &start_time)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "WriteProcessStartupTime(" << server_dir
        << "): GetProcessStartupTime failed: " << GetLastErrorString();
  }

  string start_time_file = blaze_util::JoinPath(server_dir, "server.starttime");
  if (!blaze_util::WriteFile(ToString(start_time), start_time_file)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "WriteProcessStartupTime(" << server_dir << "): WriteFile("
        << start_time_file << ") failed: " << GetLastErrorString();
  }
}

static HANDLE CreateJvmOutputFile(const wstring& path,
                                  SECURITY_ATTRIBUTES* sa,
                                  bool daemon_out_append) {
  // If the previous server process was asked to be shut down (but not killed),
  // it takes a while for it to comply, so wait until the JVM output file that
  // it held open is closed. There seems to be no better way to wait for a file
  // to be closed on Windows.
  static const unsigned int timeout_sec = 60;
  for (unsigned int waited = 0; waited < timeout_sec; ++waited) {
    HANDLE handle = ::CreateFileW(
        /* lpFileName */ path.c_str(),
        /* dwDesiredAccess */ GENERIC_READ | GENERIC_WRITE,
        /* dwShareMode */ FILE_SHARE_READ,
        /* lpSecurityAttributes */ sa,
        /* dwCreationDisposition */
            daemon_out_append ? OPEN_ALWAYS : CREATE_ALWAYS,
        /* dwFlagsAndAttributes */ FILE_ATTRIBUTE_NORMAL,
        /* hTemplateFile */ NULL);
    if (handle != INVALID_HANDLE_VALUE) {
      if (daemon_out_append
          && !SetFilePointerEx(handle, {0}, NULL, FILE_END)) {
        fprintf(stderr, "Could not seek to end of file (%ls)\n", path.c_str());
        return INVALID_HANDLE_VALUE;
      }
      return handle;
    }
    if (GetLastError() != ERROR_SHARING_VIOLATION &&
        GetLastError() != ERROR_LOCK_VIOLATION) {
      // Some other error occurred than the file being open; bail out.
      break;
    }

    // The file is still held open, the server is shutting down. There's a
    // chance that another process holds it open, we don't know; in that case
    // we just exit after the timeout expires.
    if (waited == 5 || waited == 10 || waited == 30) {
      fprintf(stderr,
              "Waiting for previous Bazel server's log file to close "
              "(waited %d seconds, waiting at most %d)\n",
              waited, timeout_sec);
    }
    Sleep(1000);
  }
  return INVALID_HANDLE_VALUE;
}

class ProcessHandleBlazeServerStartup : public BlazeServerStartup {
 public:
  ProcessHandleBlazeServerStartup(HANDLE _proc) : proc(_proc) {}

  bool IsStillAlive() override {
    FILETIME dummy1, exit_time, dummy2, dummy3;
    return GetProcessTimes(proc, &dummy1, &exit_time, &dummy2, &dummy3) &&
           exit_time.dwHighDateTime == 0 && exit_time.dwLowDateTime == 0;
  }

 private:
  AutoHandle proc;
};


int ExecuteDaemon(const string& exe,
                  const std::vector<string>& args_vector,
                  const std::map<string, EnvVarValue>& env,
                  const string& daemon_output,
                  const bool daemon_out_append,
                  const string& server_dir,
                  BlazeServerStartup** server_startup) {
  wstring wdaemon_output;
  string error;
  if (!blaze_util::AsAbsoluteWindowsPath(daemon_output, &wdaemon_output,
                                         &error)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "ExecuteDaemon(" << exe << "): AsAbsoluteWindowsPath("
        << daemon_output << ") failed: " << error;
  }

  SECURITY_ATTRIBUTES sa;
  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  // We redirect stdin to the NUL device, and redirect stdout and stderr to
  // `stdout_file` and `stderr_file` (opened below) by telling CreateProcess to
  // use these file handles, so they must be inheritable.
  sa.bInheritHandle = TRUE;
  sa.lpSecurityDescriptor = NULL;

  AutoHandle devnull(::CreateFileA("NUL", GENERIC_READ, FILE_SHARE_READ, NULL,
                                   OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
  if (!devnull.IsValid()) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "ExecuteDaemon(" << exe
        << "): CreateFileA(NUL) failed: " << GetLastErrorString();
  }

  AutoHandle stdout_file(CreateJvmOutputFile(wdaemon_output.c_str(), &sa,
                                             daemon_out_append));
  if (!stdout_file.IsValid()) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "ExecuteDaemon(" << exe << "): CreateJvmOutputFile("
        << blaze_util::WstringToString(wdaemon_output)
        << ") failed: " << GetLastErrorString();
  }
  HANDLE stderr_handle;
  // We must duplicate the handle to stdout, otherwise "bazel clean --expunge"
  // won't work, because when it tries to close stdout then stderr, the former
  // will succeed but the latter will appear to be valid yet still fail to
  // close.
  if (!DuplicateHandle(
          /* hSourceProcessHandle */ GetCurrentProcess(),
          /* hSourceHandle */ stdout_file,
          /* hTargetProcessHandle */ GetCurrentProcess(),
          /* lpTargetHandle */ &stderr_handle,
          /* dwDesiredAccess */ 0,
          /* bInheritHandle */ TRUE,
          /* dwOptions */ DUPLICATE_SAME_ACCESS)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "ExecuteDaemon(" << exe << "): DuplicateHandle("
        << blaze_util::WstringToString(wdaemon_output)
        << ") failed: " << GetLastErrorString();
  }
  AutoHandle stderr_file(stderr_handle);

  // Create an attribute list with length of 1
  AutoAttributeList lpAttributeList(1);

  HANDLE handlesToInherit[2] = {stdout_file, stderr_handle};
  if (!UpdateProcThreadAttribute(
          lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
          handlesToInherit, 2 * sizeof(HANDLE), NULL, NULL)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "ExecuteDaemon(" << exe
        << "): UpdateProcThreadAttribute failed: " << GetLastErrorString();
  }

  PROCESS_INFORMATION processInfo = {0};
  STARTUPINFOEXA startupInfoEx = {0};

  startupInfoEx.StartupInfo.cb = sizeof(startupInfoEx);
  startupInfoEx.StartupInfo.hStdInput = devnull;
  startupInfoEx.StartupInfo.hStdOutput = stdout_file;
  startupInfoEx.StartupInfo.hStdError = stderr_handle;
  startupInfoEx.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
  startupInfoEx.lpAttributeList = lpAttributeList;

  CmdLine cmdline;
  CreateCommandLine(&cmdline, exe, args_vector);

  BOOL ok;
  {
    WithEnvVars env_obj(env);

    ok = CreateProcessA(
        /* lpApplicationName */ NULL,
        /* lpCommandLine */ cmdline.cmdline,
        /* lpProcessAttributes */ NULL,
        /* lpThreadAttributes */ NULL,
        /* bInheritHandles */ TRUE,
        /* dwCreationFlags */ DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP |
        EXTENDED_STARTUPINFO_PRESENT,
        /* lpEnvironment */ NULL,
        /* lpCurrentDirectory */ NULL,
        /* lpStartupInfo */ &startupInfoEx.StartupInfo,
        /* lpProcessInformation */ &processInfo);
  }

  if (!ok) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "ExecuteDaemon(" << exe << "): CreateProcess(" << cmdline.cmdline
        << ") failed: " << GetLastErrorString();
  }

  WriteProcessStartupTime(server_dir, processInfo.hProcess);

  // Pass ownership of processInfo.hProcess
  *server_startup = new ProcessHandleBlazeServerStartup(processInfo.hProcess);

  string pid_string = ToString(processInfo.dwProcessId);
  string pid_file = blaze_util::JoinPath(server_dir, kServerPidFile);
  if (!blaze_util::WriteFile(pid_string, pid_file)) {
    // Not a lot we can do if this fails
    fprintf(stderr, "Cannot write PID file %s\n", pid_file.c_str());
  }

  // Don't close processInfo.hProcess here, it's now owned by the
  // ProcessHandleBlazeServerStartup instance.
  CloseHandle(processInfo.hThread);

  return processInfo.dwProcessId;
}

// Returns whether nested jobs are not available on the current system.
static bool NestedJobsSupported() {
  // Nested jobs are supported from Windows 8
  return IsWindows8OrGreater();
}

// Run the given program in the current working directory, using the given
// argument vector, wait for it to finish, then exit ourselves with the exitcode
// of that program.
void ExecuteProgram(const string& exe, const std::vector<string>& args_vector) {
  CmdLine cmdline;
  CreateCommandLine(&cmdline, exe, args_vector);

  STARTUPINFOA startupInfo = {0};
  startupInfo.cb = sizeof(STARTUPINFOA);

  PROCESS_INFORMATION processInfo = {0};

  HANDLE job = INVALID_HANDLE_VALUE;
  if (NestedJobsSupported()) {
    job = CreateJobObject(NULL, NULL);
    if (job == NULL) {
      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
          << "ExecuteProgram(" << exe
          << "): CreateJobObject failed: " << GetLastErrorString();
    }

    JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {0};
    job_info.BasicLimitInformation.LimitFlags =
        JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;

    if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation,
                                 &job_info, sizeof(job_info))) {
      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
          << "ExecuteProgram(" << exe
          << "): SetInformationJobObject failed: " << GetLastErrorString();
    }
  }

  BOOL success = CreateProcessA(
      /* lpApplicationName */ NULL,
      /* lpCommandLine */ cmdline.cmdline,
      /* lpProcessAttributes */ NULL,
      /* lpThreadAttributes */ NULL,
      /* bInheritHandles */ TRUE,
      /* dwCreationFlags */ CREATE_SUSPENDED,
      /* lpEnvironment */ NULL,
      /* lpCurrentDirectory */ NULL,
      /* lpStartupInfo */ &startupInfo,
      /* lpProcessInformation */ &processInfo);

  if (!success) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "ExecuteProgram(" << exe << "): CreateProcess(" << cmdline.cmdline
        << ") failed: " << GetLastErrorString();
  }

  // On Windows versions that support nested jobs (Windows 8 and above), we
  // assign the Bazel server to a job object. Every process that Bazel creates,
  // as well as all their child processes, will be assigned to this job object.
  // When the Bazel server terminates the OS can reliably kill the entire
  // process tree under it. On Windows versions that don't support nested jobs
  // (Windows 7), we don't assign the Bazel server to a big job object. Instead,
  // when Bazel creates new processes, it does so using the JNI library. The
  // library assigns individual job objects to each subprocess. This way when
  // these processes terminate, the OS can kill all their subprocesses. Bazel's
  // own subprocesses are not in a job object though, so we only create
  // subprocesses via the JNI library.
  if (job != INVALID_HANDLE_VALUE) {
    if (!AssignProcessToJobObject(job, processInfo.hProcess)) {
      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
          << "ExecuteProgram(" << exe
          << "): AssignProcessToJobObject failed: " << GetLastErrorString();
    }
  }
  // Now that we potentially put the process into a new job object, we can start
  // running it.
  if (ResumeThread(processInfo.hThread) == -1) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "ExecuteProgram(" << exe
        << "): ResumeThread failed: " << GetLastErrorString();
  }

  WaitForSingleObject(processInfo.hProcess, INFINITE);
  DWORD exit_code;
  GetExitCodeProcess(processInfo.hProcess, &exit_code);
  CloseHandle(processInfo.hProcess);
  CloseHandle(processInfo.hThread);
  exit(exit_code);
}

const char kListSeparator = ';';

bool SymlinkDirectories(const string &posix_target, const string &posix_name) {
  wstring name;
  wstring target;
  string error;
  if (!blaze_util::AsAbsoluteWindowsPath(posix_name, &name, &error)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "SymlinkDirectories(" << posix_target << ", " << posix_name
        << "): AsAbsoluteWindowsPath(" << posix_target << ") failed: " << error;
    return false;
  }
  if (!blaze_util::AsAbsoluteWindowsPath(posix_target, &target, &error)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "SymlinkDirectories(" << posix_target << ", " << posix_name
        << "): AsAbsoluteWindowsPath(" << posix_name << ") failed: " << error;
    return false;
  }
  wstring werror;
  if (CreateJunction(name, target, &werror) != CreateJunctionResult::kSuccess) {
    string error(blaze_util::WstringToCstring(werror.c_str()).get());
    BAZEL_LOG(ERROR) << "SymlinkDirectories(" << posix_target << ", "
                     << posix_name << "): CreateJunction: " << error;
    return false;
  }
  return true;
}


#ifndef STILL_ACTIVE
#define STILL_ACTIVE (259)  // From MSDN about GetExitCodeProcess.
#endif

// On Windows (and Linux) we use a combination of PID and start time to identify
// the server process. That is supposed to be unique unless one can start more
// processes than there are PIDs available within a single jiffy.
bool VerifyServerProcess(int pid, const string& output_base) {
  AutoHandle process(
      ::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid));
  if (!process.IsValid()) {
    // Cannot find the server process. Can happen if the PID file is stale.
    return false;
  }

  DWORD exit_code = 0;
  uint64_t start_time = 0;
  if (!::GetExitCodeProcess(process, &exit_code) || exit_code != STILL_ACTIVE ||
      !GetProcessStartupTime(process, &start_time)) {
    // Process doesn't exist or died meantime, all is good. No stale server is
    // present.
    return false;
  }

  string recorded_start_time;
  bool file_present = blaze_util::ReadFile(
      blaze_util::JoinPath(output_base, "server/server.starttime"),
      &recorded_start_time);

  // If start time file got deleted, but PID file didn't, assume that this is an
  // old Bazel process that doesn't know how to write start time files yet.
  return !file_present || recorded_start_time == ToString(start_time);
}

bool KillServerProcess(int pid, const string& output_base) {
  AutoHandle process(::OpenProcess(
      PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid));
  DWORD exitcode = 0;
  if (!process.IsValid() || !::GetExitCodeProcess(process, &exitcode) ||
      exitcode != STILL_ACTIVE) {
    // Cannot find the server process (can happen if the PID file is stale) or
    // it already exited.
    return false;
  }

  BOOL result = TerminateProcess(process, /*uExitCode*/ 0);
  if (!result || !AwaitServerProcessTermination(pid, output_base,
                                                kPostKillGracePeriodSeconds)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "Cannot terminate server process with PID " << pid
        << ", output_base=(" << output_base << "): " << GetLastErrorString();
  }
  return result;
}

void TrySleep(unsigned int milliseconds) {
  Sleep(milliseconds);
}

// Not supported.
void ExcludePathFromBackup(const string &path) {
}

string GetHashedBaseDir(const string& root, const string& hashable) {
  // Builds a shorter output base dir name for Windows.

  // We create a path name representing the 128 bits of MD5 digest. To avoid
  // platform incompatibilities we restrict the alphabet to ASCII letters and
  // numbers. Windows paths are case-insensitive, so use only lower-case
  // letters. These constraints yield a 5-bit alphabet.
  // Since we only need 6 digits, ignore 0 and 1 because they look like
  // upper-case "O" and lower-case "l".
  static const char* alphabet = "abcdefghijklmnopqrstuvwxyz234567";

  // 128 bits of data in base-32 require 128/5 = 25 digits with 3 bits lost.
  // Maximum path length on Windows is only 259 characters, so we'll only use
  // a few characters characters (base-32 digits) to represent the digest.
  // Using only 8 characters we represent 40 bits of the original 128.
  // Since the mapping is lossy and collisions are unlikely in practice, we'll
  // keep the mapping simple and just use the lower 5 bits of the first 8 bytes.
  static const unsigned char kLower5BitsMask = 0x1F;
  static const int filename_length = 8;
  unsigned char md5[blaze_util::Md5Digest::kDigestLength];
  char coded_name[filename_length + 1];
  blaze_util::Md5Digest digest;
  digest.Update(hashable.data(), hashable.size());
  digest.Finish(md5);
  for (int i = 0; i < filename_length; ++i) {
    coded_name[i] = alphabet[md5[i] & kLower5BitsMask];
  }
  coded_name[filename_length] = '\0';
  return blaze_util::JoinPath(root, string(coded_name));
}

void CreateSecureOutputRoot(const string& path) {
  // TODO(bazel-team): implement this properly, by mimicing whatever the POSIX
  // implementation does.
  const char* root = path.c_str();
  if (!blaze_util::MakeDirectories(path, 0755)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "MakeDirectories(" << root << ") failed: " << GetLastErrorString();
  }

  if (!blaze_util::IsDirectory(path)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "'" << root << "' is not a directory";
  }

  ExcludePathFromBackup(root);
}

string GetEnv(const string& name) {
  DWORD size = ::GetEnvironmentVariableA(name.c_str(), NULL, 0);
  if (size == 0) {
    return string();  // unset or empty envvar
  }

  unique_ptr<char[]> value(new char[size]);
  ::GetEnvironmentVariableA(name.c_str(), value.get(), size);
  return string(value.get());
}

bool ExistsEnv(const string& name) {
  return ::GetEnvironmentVariableA(name.c_str(), NULL, 0) != 0;
}

void SetEnv(const string& name, const string& value) {
  // _putenv_s both calls ::SetEnvionmentVariableA and updates environ(5).
  _putenv_s(name.c_str(), value.c_str());
}

void UnsetEnv(const string& name) { SetEnv(name, ""); }

bool WarnIfStartedFromDesktop() {
  // GetConsoleProcessList returns:
  //   0, if no console attached (Bazel runs as a subprocess)
  //   1, if Bazel was started by clicking on its icon
  //   2, if Bazel was started from the command line (even if its output is
  //      redirected)
  DWORD dummy[2] = {0};
  if (GetConsoleProcessList(dummy, 2) != 1) {
    return false;
  }
  printf(
      "Bazel is a command line tool.\n\n"
      "Try opening a console, such as the Windows Command Prompt (cmd.exe) "
      "or PowerShell, and running \"bazel help\".\n\n"
      "Press Enter to close this window...");
  ReadFile(GetStdHandle(STD_INPUT_HANDLE), dummy, 1, dummy, NULL);
  return true;
}

#ifndef ENABLE_PROCESSED_OUTPUT
// From MSDN about BOOL SetConsoleMode(HANDLE, DWORD).
#define ENABLE_PROCESSED_OUTPUT 0x0001
#endif  // not ENABLE_PROCESSED_OUTPUT

#ifndef ENABLE_WRAP_AT_EOL_OUTPUT
// From MSDN about BOOL SetConsoleMode(HANDLE, DWORD).
#define ENABLE_WRAP_AT_EOL_OUTPUT 0x0002
#endif  // not ENABLE_WRAP_AT_EOL_OUTPUT

#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
// From MSDN about BOOL SetConsoleMode(HANDLE, DWORD).
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif  // not ENABLE_VIRTUAL_TERMINAL_PROCESSING

void SetupStdStreams() {
  static const DWORD stdhandles[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
                                     STD_ERROR_HANDLE};
  for (int i = 0; i <= 2; ++i) {
    HANDLE handle = ::GetStdHandle(stdhandles[i]);
    if (handle == INVALID_HANDLE_VALUE || handle == NULL) {
      // Ensure we have open fds to each std* stream. Otherwise we can end up
      // with bizarre things like stdout going to the lock file, etc.
      _open("NUL", (i == 0) ? _O_RDONLY : _O_WRONLY);
    }
    DWORD mode = 0;
    if (i > 0 && handle != INVALID_HANDLE_VALUE && handle != NULL &&
        ::GetConsoleMode(handle, &mode)) {
      DWORD newmode = mode | ENABLE_PROCESSED_OUTPUT |
                      ENABLE_WRAP_AT_EOL_OUTPUT |
                      ENABLE_VIRTUAL_TERMINAL_PROCESSING;
      if (mode != newmode) {
        // We don't care about the success of this. Worst that can happen if
        // this method fails is that the console won't understand control
        // characters like color change or carriage return.
        ::SetConsoleMode(handle, newmode);
      }
    }
  }
}

LARGE_INTEGER WindowsClock::GetFrequency() {
  LARGE_INTEGER result;
  if (!QueryPerformanceFrequency(&result)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "WindowsClock::GetFrequency: QueryPerformanceFrequency failed: "
        << GetLastErrorString();
  }

  // On ancient Windows versions (pre-XP) and specific hardware the result may
  // be 0. Since this is pre-XP, we don't handle that, just error out.
  if (result.QuadPart <= 0) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "WindowsClock::GetFrequency: QueryPerformanceFrequency returned "
           "invalid result ("
        << result.QuadPart << "): " << GetLastErrorString();
  }

  return result;
}

LARGE_INTEGER WindowsClock::GetMillisecondsAsLargeInt(
    const LARGE_INTEGER& freq) {
  LARGE_INTEGER counter;
  if (!QueryPerformanceCounter(&counter)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "WindowsClock::GetMillisecondsAsLargeInt: QueryPerformanceCounter "
           "failed: "
        << GetLastErrorString();
  }

  LARGE_INTEGER result;
  result.QuadPart =
      // seconds
      (counter.QuadPart / freq.QuadPart) * 1000LL +
      // milliseconds
      (((counter.QuadPart % freq.QuadPart) * 1000LL) / freq.QuadPart);

  return result;
}

const WindowsClock WindowsClock::INSTANCE;

WindowsClock::WindowsClock()
    : kFrequency(GetFrequency()) {}

uint64_t WindowsClock::GetMilliseconds() const {
  return GetMillisecondsAsLargeInt(kFrequency).QuadPart;
}

uint64_t AcquireLock(const string& output_base, bool batch_mode, bool block,
                     BlazeLock* blaze_lock) {
  string lockfile = blaze_util::JoinPath(output_base, "lock");
  wstring wlockfile;
  string error;
  if (!blaze_util::AsAbsoluteWindowsPath(lockfile, &wlockfile, &error)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "AcquireLock(" << output_base << "): AsAbsoluteWindowsPath("
        << lockfile << ") failed: " << error;
  }

  blaze_lock->handle = INVALID_HANDLE_VALUE;
  bool first_lock_attempt = true;
  uint64_t st = GetMillisecondsMonotonic();
  while (true) {
    blaze_lock->handle = ::CreateFileW(
        /* lpFileName */ wlockfile.c_str(),
        /* dwDesiredAccess */ GENERIC_READ | GENERIC_WRITE,
        /* dwShareMode */ FILE_SHARE_READ,
        /* lpSecurityAttributes */ NULL,
        /* dwCreationDisposition */ CREATE_ALWAYS,
        /* dwFlagsAndAttributes */ FILE_ATTRIBUTE_NORMAL,
        /* hTemplateFile */ NULL);
    if (blaze_lock->handle != INVALID_HANDLE_VALUE) {
      // We could open the file, so noone else holds a lock on it.
      break;
    }
    if (GetLastError() == ERROR_SHARING_VIOLATION) {
      // Someone else has the lock.
      BAZEL_LOG(USER) << "Another command holds the client lock";
      if (!block) {
        BAZEL_DIE(blaze_exit_code::LOCK_HELD_NOBLOCK_FOR_LOCK)
            << "Exiting because the lock is held and --noblock_for_lock was "
               "given.";
      }
      if (first_lock_attempt) {
        first_lock_attempt = false;
        BAZEL_LOG(USER) << "Waiting for it to complete...";
        fflush(stderr);
      }
      Sleep(/* dwMilliseconds */ 200);
    } else {
      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
          << "AcquireLock(" << lockfile << "): CreateFileW("
          << blaze_util::WstringToString(wlockfile)
          << ") failed: " << GetLastErrorString();
    }
  }
  uint64_t wait_time = GetMillisecondsMonotonic() - st;

  // We have the lock.
  OVERLAPPED overlapped = {0};
  if (!LockFileEx(
          /* hFile */ blaze_lock->handle,
          /* dwFlags */ LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
          /* dwReserved */ 0,
          /* nNumberOfBytesToLockLow */ 1,
          /* nNumberOfBytesToLockHigh */ 0,
          /* lpOverlapped */ &overlapped)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "AcquireLock(" << lockfile << "): LockFileEx("
        << blaze_util::WstringToString(wlockfile)
        << ") failed: " << GetLastErrorString();
  }
  // On other platforms we write some info about this process into the lock file
  // such as the server PID. On Windows we don't do that because the file is
  // locked exclusively, meaning other processes may not open the file even for
  // reading.

  return wait_time;
}

void ReleaseLock(BlazeLock* blaze_lock) {
  OVERLAPPED overlapped = {0};
  UnlockFileEx(blaze_lock->handle, 0, 1, 0, &overlapped);
  CloseHandle(blaze_lock->handle);
}

#ifdef GetUserName
// By including <windows.h>, we have GetUserName defined either as
// GetUserNameA or GetUserNameW.
#undef GetUserName
#endif

string GetUserName() {
  WCHAR buffer[UNLEN + 1];
  DWORD len = UNLEN + 1;
  if (!::GetUserNameW(buffer, &len)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "GetUserNameW failed: " << GetLastErrorString();
  }
  return string(blaze_util::WstringToCstring(buffer).get());
}

bool IsEmacsTerminal() {
  string emacs = GetEnv("EMACS");
  string inside_emacs = GetEnv("INSIDE_EMACS");
  // GNU Emacs <25.1 (and ~all non-GNU emacsen) set EMACS=t, but >=25.1 doesn't
  // do that and instead sets INSIDE_EMACS=<stuff> (where <stuff> can look like
  // e.g. "25.1.1,comint").  So we check both variables for maximum
  // compatibility.
  return emacs == "t" || !inside_emacs.empty();
}

// Returns true if stderr is connected to a terminal, and it can support color
// and cursor movement (this is computed heuristically based on the values of
// environment variables).  Blaze only outputs control characters to stderr,
// so we only care for the stderr descriptor type.
bool IsStderrStandardTerminal() {
  DWORD mode = 0;
  HANDLE handle = ::GetStdHandle(STD_ERROR_HANDLE);
  // handle may be invalid when stderr is redirected
  if (handle == INVALID_HANDLE_VALUE || !::GetConsoleMode(handle, &mode) ||
      !(mode & ENABLE_PROCESSED_OUTPUT) ||
      !(mode & ENABLE_WRAP_AT_EOL_OUTPUT) ||
      !(mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
    return false;
  }
  return true;
}

// Returns the number of columns of the terminal to which stderr is connected,
// or $COLUMNS (default 80) if there is no such terminal.  Blaze only outputs
// formatted messages to stderr, so we only care for width of a terminal
// connected to the stderr descriptor.
int GetStderrTerminalColumns() {
  string columns_env = GetEnv("COLUMNS");
  if (!columns_env.empty()) {
    char* endptr;
    int columns = blaze_util::strto32(columns_env.c_str(), &endptr, 10);
    if (*endptr == '\0') {  // $COLUMNS is a valid number
      return columns;
    }
  }

  HANDLE stdout_handle = ::GetStdHandle(STD_ERROR_HANDLE);
  if (stdout_handle != INVALID_HANDLE_VALUE) {
    // stdout_handle may be invalid when stdout is redirected.
    CONSOLE_SCREEN_BUFFER_INFO screen_info;
    if (GetConsoleScreenBufferInfo(stdout_handle, &screen_info)) {
      int width = 1 + screen_info.srWindow.Right - screen_info.srWindow.Left;
      if (width > 1) {
        return width;
      }
    }
  }

  return 80;  // default if not a terminal.
}

bool UnlimitResources() {
  return true;  // Nothing to do so assume success.
}

bool UnlimitCoredumps() {
  return true;  // Nothing to do so assume success.
}

static const int MAX_KEY_LENGTH = 255;
// We do not care about registry values longer than MAX_PATH
static const int REG_VALUE_BUFFER_SIZE = MAX_PATH;

// Implements heuristics to discover msys2 installation.
static string GetMsysBash() {
  HKEY h_uninstall;

  // MSYS2 installer writes its registry into HKCU, although documentation
  // (https://msdn.microsoft.com/en-us/library/ms954376.aspx)
  // clearly states that it should go to HKLM.
  static constexpr const char key[] =
      "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
  if (RegOpenKeyExA(HKEY_CURRENT_USER,  // _In_     HKEY    hKey,
                    key,                // _In_opt_ LPCTSTR lpSubKey,
                    0,                  // _In_     DWORD   ulOptions,
                    KEY_ENUMERATE_SUB_KEYS |
                        KEY_QUERY_VALUE,  // _In_     REGSAM  samDesired,
                    &h_uninstall          // _Out_    PHKEY   phkResult
                    )) {
    BAZEL_LOG(INFO) << "Cannot open HKCU\\" << key;
    return string();
  }
  AutoHandle auto_uninstall(h_uninstall);

  // Since MSYS2 decided to generate a new product key for each installation,
  // we enumerate all keys under
  // HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall and find the first
  // with MSYS2 64bit display name.
  static constexpr const char msys_display_name[] = "MSYS2 64bit";
  DWORD n_subkeys;

  if (RegQueryInfoKey(h_uninstall,  // _In_        HKEY      hKey,
                      0,            // _Out_opt_   LPTSTR    lpClass,
                      0,            // _Inout_opt_ LPDWORD   lpcClass,
                      0,            // _Reserved_  LPDWORD   lpReserved,
                      &n_subkeys,   // _Out_opt_   LPDWORD   lpcSubKeys,
                      0,            // _Out_opt_   LPDWORD   lpcMaxSubKeyLen,
                      0,            // _Out_opt_   LPDWORD   lpcMaxClassLen,
                      0,            // _Out_opt_   LPDWORD   lpcValues,
                      0,            // _Out_opt_   LPDWORD   lpcMaxValueNameLen,
                      0,            // _Out_opt_   LPDWORD   lpcMaxValueLen,
                      0,  // _Out_opt_   LPDWORD   lpcbSecurityDescriptor,
                      0   // _Out_opt_   PFILETIME lpftLastWriteTime
                      )) {
    BAZEL_LOG(INFO) << "Cannot query HKCU\\" << key;
    return string();
  }

  for (DWORD key_index = 0; key_index < n_subkeys; key_index++) {
    char subkey_name[MAX_KEY_LENGTH];
    if (RegEnumKeyA(h_uninstall,         // _In_  HKEY   hKey,
                    key_index,           // _In_  DWORD  dwIndex,
                    subkey_name,         // _Out_ LPTSTR lpName,
                    sizeof(subkey_name)  // _In_  DWORD  cchName
                    )) {
      BAZEL_LOG(INFO) << "Cannot get " << key_index << " subkey of HKCU\\"
                      << key;
      continue;  // try next subkey
    }

    HKEY h_subkey;
    if (RegOpenKeyEx(h_uninstall,      // _In_     HKEY    hKey,
                     subkey_name,      // _In_opt_ LPCTSTR lpSubKey,
                     0,                // _In_     DWORD   ulOptions,
                     KEY_QUERY_VALUE,  // _In_     REGSAM  samDesired,
                     &h_subkey         // _Out_    PHKEY   phkResult
                     )) {
      BAZEL_LOG(ERROR) << "Failed to open subkey HKCU\\" << key << "\\"
                       << subkey_name;
      continue;  // try next subkey
    }
    AutoHandle auto_subkey(h_subkey);

    BYTE value[REG_VALUE_BUFFER_SIZE];
    DWORD value_length = sizeof(value);
    DWORD value_type;

    if (RegQueryValueEx(h_subkey,       // _In_        HKEY    hKey,
                        "DisplayName",  // _In_opt_    LPCTSTR lpValueName,
                        0,              // _Reserved_  LPDWORD lpReserved,
                        &value_type,    // _Out_opt_   LPDWORD lpType,
                        value,          // _Out_opt_   LPBYTE  lpData,
                        &value_length   // _Inout_opt_ LPDWORD lpcbData
                        )) {
      BAZEL_LOG(ERROR) << "Failed to query DisplayName of HKCU\\" << key << "\\"
                       << subkey_name;
      continue;  // try next subkey
    }

    if (value_type == REG_SZ &&
        0 == memcmp(msys_display_name, value, sizeof(msys_display_name))) {
      BAZEL_LOG(INFO) << "Getting install location of HKCU\\" << key << "\\"
                      << subkey_name;
      BYTE path[REG_VALUE_BUFFER_SIZE];
      DWORD path_length = sizeof(path);
      DWORD path_type;
      if (RegQueryValueEx(
              h_subkey,           // _In_        HKEY    hKey,
              "InstallLocation",  // _In_opt_    LPCTSTR lpValueName,
              0,                  // _Reserved_  LPDWORD lpReserved,
              &path_type,         // _Out_opt_   LPDWORD lpType,
              path,               // _Out_opt_   LPBYTE  lpData,
              &path_length        // _Inout_opt_ LPDWORD lpcbData
              )) {
        BAZEL_LOG(ERROR) << "Failed to query InstallLocation of HKCU\\" << key
                         << "\\" << subkey_name;
        continue;  // try next subkey
      }

      if (path_length == 0 || path_type != REG_SZ) {
        BAZEL_LOG(ERROR) << "Zero-length (" << path_length
                         << ") install location or wrong type (" << path_type
                         << ")";
        continue;  // try next subkey
      }

      BAZEL_LOG(INFO) << "Install location of HKCU\\" << key << "\\"
                      << subkey_name << " is " << path;
      string path_as_string(path, path + path_length - 1);
      string bash_exe = path_as_string + "\\usr\\bin\\bash.exe";
      if (!blaze_util::PathExists(bash_exe)) {
        BAZEL_LOG(INFO) << bash_exe.c_str() << " does not exist";
        continue;  // try next subkey
      }

      BAZEL_LOG(INFO) << "Detected msys bash at " << bash_exe.c_str();
      return bash_exe;
    }
  }
  return string();
}

static string GetBinaryFromPath(const string& binary_name) {
  char found[MAX_PATH];
  string path_list = blaze::GetEnv("PATH");

  // We do not fully replicate all the quirks of search in PATH.
  // There is no system function to do so, and that way lies madness.
  size_t start = 0;
  do {
    // This ignores possibly quoted semicolons in PATH etc.
    size_t end = path_list.find_first_of(";", start);
    string path = path_list.substr(
        start, end != string::npos ? end - start : string::npos);
    // Handle one typical way of quoting (where.exe does not handle this, but
    // CreateProcess does).
    if (path.size() > 1 && path[0] == '"' && path[path.size() - 1] == '"') {
      path = path.substr(1, path.size() - 2);
    }
    if (SearchPathA(path.c_str(),         // _In_opt_  LPCTSTR lpPath,
                    binary_name.c_str(),  // _In_      LPCTSTR lpFileName,
                    0,                    // LPCTSTR lpExtension,
                    sizeof(found),        // DWORD   nBufferLength,
                    found,                // _Out_     LPTSTR  lpBuffer,
                    0                     // _Out_opt_ LPTSTR  *lpFilePart
                    )) {
      BAZEL_LOG(INFO) << binary_name.c_str() << " found on PATH: " << found;
      return string(found);
    }
    if (end == string::npos) {
      break;
    }
    start = end + 1;
  } while (true);

  return string();
}

static string LocateBash() {
  string msys_bash = GetMsysBash();
  if (!msys_bash.empty()) {
    return msys_bash;
  }

  string result = GetBinaryFromPath("bash.exe");
  if (result.empty()) {
    BAZEL_LOG(ERROR) << "bash.exe not found on PATH";
  }
  return result;
}

void DetectBashOrDie() {
  if (!blaze::GetEnv("BAZEL_SH").empty()) return;

  uint64_t start = blaze::GetMillisecondsMonotonic();

  string bash = LocateBash();
  uint64_t end = blaze::GetMillisecondsMonotonic();
  BAZEL_LOG(INFO) << "BAZEL_SH detection took " << end - start
                  << " msec, found " << bash.c_str();

  if (!bash.empty()) {
    // Set process environment variable.
    blaze::SetEnv("BAZEL_SH", bash);
  } else {
    // TODO(bazel-team) should this be printed to stderr? If so, it should use
    // BAZEL_LOG(ERROR)
    printf(
        "Bazel on Windows requires MSYS2 Bash, but we could not find it.\n"
        "If you do not have it installed, you can install MSYS2 from\n"
        "       http://repo.msys2.org/distrib/msys2-x86_64-latest.exe\n"
        "\n"
        "If you already have it installed but Bazel cannot find it,\n"
        "set BAZEL_SH environment variable to its location:\n"
        "       set BAZEL_SH=c:\\path\\to\\msys2\\usr\\bin\\bash.exe\n");
    exit(1);
  }
}

void EnsurePythonPathOption(std::vector<string>* options) {
  string python_path = GetBinaryFromPath("python.exe");
  if (!python_path.empty()) {
    // Provide python path as coming from the least important rc file.
    std::replace(python_path.begin(), python_path.end(), '\\', '/');
    options->push_back(string("--default_override=0:build=--python_path=") +
                       python_path);
  }
}

}  // namespace blaze
