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

#define WIN32_LEAN_AND_MEAN

#include <wchar.h>
#include <windows.h>

#include <atomic>
#include <memory>
#include <sstream>
#include <string>
#include <type_traits>  // static_assert

#include "src/main/native/jni.h"
#include "src/main/native/windows/jni-util.h"
#include "src/main/native/windows/util.h"

// Maximum command line length is 2^15 characters including the null terminator.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
static const size_t MAX_CMDLINE = 1 << 15;

template <typename T>
static std::wstring ToString(const T& e) {
  std::wstringstream s;
  s << e;
  return s.str();
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetpid(
    JNIEnv* env, jclass clazz) {
  return GetCurrentProcessId();
}

struct NativeOutputStream {
  HANDLE handle_;
  std::wstring error_;
  std::atomic<bool> closed_;
  NativeOutputStream()
      : handle_(INVALID_HANDLE_VALUE), error_(L""), closed_(false) {}

  void close() {
    closed_.store(true);
    if (handle_ == INVALID_HANDLE_VALUE) {
      return;
    }

    // CancelIoEx only cancels I/O operations in the current process.
    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363792(v=vs.85).aspx
    //
    // Therefore if this process bequested `handle_` to a child process, we
    // cannot cancel I/O in the child process.
    CancelIoEx(handle_, NULL);
    CloseHandle(handle_);
    handle_ = INVALID_HANDLE_VALUE;
  }
};

static std::wstring AddUncPrefixMaybe(const std::wstring& path) {
  return (path.size() >= MAX_PATH) ? (std::wstring(L"\\\\?\\") + path) : path;
}

struct NativeProcess {
  HANDLE stdin_;
  NativeOutputStream stdout_;
  NativeOutputStream stderr_;
  HANDLE process_;
  HANDLE job_;
  DWORD pid_;
  std::wstring error_;

  NativeProcess()
      : stdin_(INVALID_HANDLE_VALUE),
        stdout_(),
        stderr_(),
        process_(INVALID_HANDLE_VALUE),
        job_(INVALID_HANDLE_VALUE),
        error_(L"") {}
};

class JavaByteArray {
 public:
  JavaByteArray(JNIEnv* env, jbyteArray java_array)
      : env_(env),
        array_(java_array),
        size_(java_array != nullptr ? env->GetArrayLength(java_array) : 0),
        ptr_(java_array != nullptr ? env->GetByteArrayElements(java_array, NULL)
                                   : nullptr) {}

  ~JavaByteArray() {
    if (array_ != nullptr) {
      env_->ReleaseByteArrayElements(array_, ptr_, 0);
      array_ = nullptr;
      size_ = 0;
      ptr_ = nullptr;
    }
  }

  jsize size() { return size_; }
  jbyte* ptr() { return ptr_; }

 private:
  JNIEnv* env_;
  jbyteArray array_;
  jsize size_;
  jbyte* ptr_;
};

static bool NestedJobsSupported() {
  OSVERSIONINFOEX version_info;
  version_info.dwOSVersionInfoSize = sizeof(version_info);
  if (!GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info))) {
    return false;
  }

  return version_info.dwMajorVersion > 6 ||
         version_info.dwMajorVersion == 6 && version_info.dwMinorVersion >= 2;
}

// Ensure we can safely cast jlong to void*.
static_assert(sizeof(jlong) == sizeof(void*),
              "jlong and void* should be the same size");

static_assert(sizeof(jchar) == sizeof(WCHAR),
              "jchar and WCHAR should be the same size");

static jlong PtrAsJlong(void* p) { return reinterpret_cast<jlong>(p); }

// The following CreateProcessWithExplicitHandles function is based on an
// implementation of the same function in the following OldNewThing blog post:
// https://blogs.msdn.microsoft.com/oldnewthing/20111216-00/?p=8873
// We need this function to prevent the child process from inheriting unintended
// handles. See http://support.microsoft.com/kb/315939
static std::wstring CreateProcessWithExplicitHandles(
    /* __inout_opt */ LPWSTR lpCommandLine,
    /* __in_opt    */ LPVOID lpEnvironment,
    /* __in_opt    */ LPCWSTR lpCurrentDirectory,
    /* __in        */ LPSTARTUPINFOW lpStartupInfo,
    /* __out       */ LPPROCESS_INFORMATION lpProcessInformation,
    /* __in        */ DWORD cHandlesToInherit,
    /* __in_ecount(cHandlesToInherit) */ HANDLE* handlesToInherit) {
  if (wcsnlen_s(lpCommandLine, MAX_CMDLINE) == MAX_CMDLINE) {
    std::wstring cmd_sample(lpCommandLine, 200);
    cmd_sample.append(L"(...)");
    std::wstringstream error_msg;
    error_msg << L"command is longer than CreateProcessW's limit ("
              << MAX_CMDLINE << L" characters)";
    return bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"CreateProcessWithExplicitHandles",
        cmd_sample.c_str(), error_msg.str().c_str());
  }

  if (cHandlesToInherit >= 0xFFFFFFFF / sizeof(HANDLE)) {
    return bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"CreateProcessWithExplicitHandles",
        lpCommandLine, L"too many handles to inherit");
  }

  if (lpStartupInfo->cb != sizeof(*lpStartupInfo)) {
    return bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"CreateProcessWithExplicitHandles",
        lpCommandLine, L"bad lpStartupInfo");
  }

  SIZE_T size = 0;
  if (!InitializeProcThreadAttributeList(NULL, 1, 0, &size) &&
      GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
    DWORD err_code = GetLastError();
    return bazel::windows::MakeErrorMessage(WSTR(__FILE__), __LINE__,
                                            L"CreateProcessWithExplicitHandles",
                                            lpCommandLine, err_code);
  }

  LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList =
      reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(
          HeapAlloc(GetProcessHeap(), 0, size));
  if (lpAttributeList == NULL) {
    DWORD err_code = GetLastError();
    return bazel::windows::MakeErrorMessage(WSTR(__FILE__), __LINE__,
                                            L"CreateProcessWithExplicitHandles",
                                            lpCommandLine, err_code);
  }

  if (!InitializeProcThreadAttributeList(lpAttributeList, 1, 0, &size)) {
    DWORD err_code = GetLastError();
    return bazel::windows::MakeErrorMessage(WSTR(__FILE__), __LINE__,
                                            L"CreateProcessWithExplicitHandles",
                                            lpCommandLine, err_code);
  }
  if (!UpdateProcThreadAttribute(
          lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
          handlesToInherit, cHandlesToInherit * sizeof(HANDLE), NULL, NULL)) {
    DWORD err_code = GetLastError();
    return bazel::windows::MakeErrorMessage(WSTR(__FILE__), __LINE__,
                                            L"CreateProcessWithExplicitHandles",
                                            lpCommandLine, err_code);
  }

  STARTUPINFOEXW info;
  ZeroMemory(&info, sizeof(info));
  info.StartupInfo = *lpStartupInfo;
  info.StartupInfo.cb = sizeof(info);
  info.lpAttributeList = lpAttributeList;
  DWORD createproc_err = 0;
  if (!CreateProcessW(
          /* lpApplicationName */ NULL,
          /* lpCommandLine */ lpCommandLine,
          /* lpProcessAttributes */ NULL,
          /* lpThreadAttributes */ NULL,
          /* bInheritHandles */ TRUE,
          /* dwCreationFlags */ CREATE_NO_WINDOW  // Don't create console window
              | CREATE_NEW_PROCESS_GROUP  // So that Ctrl-Break isn't propagated
              | CREATE_SUSPENDED  // So that it doesn't start a new job itself
              | EXTENDED_STARTUPINFO_PRESENT,
          /* lpEnvironment */ lpEnvironment,
          /* lpCurrentDirectory */ lpCurrentDirectory,
          /* lpStartupInfo */ &info.StartupInfo,
          /* lpProcessInformation */ lpProcessInformation)) {
    createproc_err = GetLastError();
  }

  DeleteProcThreadAttributeList(lpAttributeList);
  if (lpAttributeList) {
    HeapFree(GetProcessHeap(), 0, lpAttributeList);
  }
  if (createproc_err) {
    return bazel::windows::MakeErrorMessage(WSTR(__FILE__), __LINE__,
                                            L"CreateProcessW", lpCommandLine,
                                            createproc_err);
  }
  return L"";
}

extern "C" JNIEXPORT jlong JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeCreateProcess(
    JNIEnv* env, jclass clazz, jstring java_argv0, jstring java_argv_rest,
    jbyteArray java_env, jstring java_cwd, jstring java_stdout_redirect,
    jstring java_stderr_redirect, jboolean redirectErrorStream) {
  NativeProcess* result = new NativeProcess();

  std::wstring argv0;
  std::wstring wpath(bazel::windows::GetJavaWstring(env, java_argv0));
  std::wstring error_msg(
      bazel::windows::AsExecutablePathForCreateProcess(wpath, &argv0));
  if (!error_msg.empty()) {
    result->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, error_msg);
    return PtrAsJlong(result);
  }

  std::wstring commandline =
      argv0 + L" " + bazel::windows::GetJavaWstring(env, java_argv_rest);
  std::wstring stdout_redirect = AddUncPrefixMaybe(
      bazel::windows::GetJavaWstring(env, java_stdout_redirect));
  std::wstring stderr_redirect = AddUncPrefixMaybe(
      bazel::windows::GetJavaWstring(env, java_stderr_redirect));
  std::wstring cwd;
  std::wstring wcwd(bazel::windows::GetJavaWstring(env, java_cwd));
  error_msg = bazel::windows::AsShortPath(wcwd, &cwd);
  if (!error_msg.empty()) {
    result->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, error_msg);
    return PtrAsJlong(result);
  }

  std::unique_ptr<WCHAR[]> mutable_commandline(
      new WCHAR[commandline.size() + 1]);
  wcsncpy(mutable_commandline.get(), commandline.c_str(),
          commandline.size() + 1);

  SECURITY_ATTRIBUTES sa = {0};
  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle = TRUE;

  // Standard file handles are closed even if the process was successfully
  // created. If this was not so, operations on these file handles would not
  // return immediately if the process is terminated.
  // Therefore we make these handles auto-closing (by using AutoHandle).
  bazel::windows::AutoHandle stdin_process;
  bazel::windows::AutoHandle stdout_process;
  bazel::windows::AutoHandle stderr_process;
  bazel::windows::AutoHandle thread;
  PROCESS_INFORMATION process_info = {0};
  STARTUPINFOW startup_info = {0};
  JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {0};

  JavaByteArray env_map(env, java_env);
  if (env_map.ptr() != nullptr) {
    if (env_map.size() < 2) {
      result->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath,
          L"the environment must be at least two bytes long");
      return PtrAsJlong(result);
    } else if (env_map.ptr()[env_map.size() - 1] != 0 ||
               env_map.ptr()[env_map.size() - 2] != 0) {
      result->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath,
          L"environment array must end with two null bytes");
      return PtrAsJlong(result);
    }
  }

  HANDLE temp_stdin_handle = INVALID_HANDLE_VALUE;
  if (!CreatePipe(&temp_stdin_handle, &result->stdin_, &sa, 0)) {
    DWORD err_code = GetLastError();
    result->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
    CloseHandle(temp_stdin_handle);
    return PtrAsJlong(result);
  }
  stdin_process = temp_stdin_handle;

  if (!stdout_redirect.empty()) {
    result->stdout_.close();

    stdout_process = CreateFileW(
        /* lpFileName */ stdout_redirect.c_str(),
        /* dwDesiredAccess */ FILE_APPEND_DATA,
        /* dwShareMode */ 0,
        /* lpSecurityAttributes */ &sa,
        /* dwCreationDisposition */ OPEN_ALWAYS,
        /* dwFlagsAndAttributes */ FILE_ATTRIBUTE_NORMAL,
        /* hTemplateFile */ NULL);

    if (!stdout_process.IsValid()) {
      DWORD err_code = GetLastError();
      result->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
      return PtrAsJlong(result);
    }
  } else {
    HANDLE temp_stdout_handle = INVALID_HANDLE_VALUE;
    if (!CreatePipe(&result->stdout_.handle_, &temp_stdout_handle, &sa, 0)) {
      DWORD err_code = GetLastError();
      result->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
      CloseHandle(temp_stdout_handle);
      return PtrAsJlong(result);
    }
    stdout_process = temp_stdout_handle;
  }

  // The value of the stderr HANDLE.
  // If stdout and stderr are redirected to the same file, this will be equal to
  // stdout_process.handle and stderr_process.handle will be
  // INVALID_HANDLE_VALUE, so the two AutoHandle objects' d'tors will not
  // attempt to close stdout's handle twice.
  // If stdout != stderr, then stderr_handle = stderr_process.handle, and these
  // are distinct from stdout_process.handle, so again the d'tors will do the
  // right thing, closing the handles.
  // In both cases, we DO NOT close stderr_handle, since it's either
  // stdout_process's or stderr_process's d'tor doing so.
  HANDLE stderr_handle = INVALID_HANDLE_VALUE;

  if (redirectErrorStream) {
    stderr_handle = stdout_process;
  } else if (!stderr_redirect.empty()) {
    result->stderr_.close();
    if (stdout_redirect == stderr_redirect) {
      stderr_handle = stdout_process;
      // do not set stderr_process.handle; it equals stdout_process.handle and
      // the AutoHandle d'tor would attempt to close it again
    } else {
      stderr_handle = CreateFileW(
          /* lpFileName */ stderr_redirect.c_str(),
          /* dwDesiredAccess */ FILE_APPEND_DATA,
          /* dwShareMode */ 0,
          /* lpSecurityAttributes */ &sa,
          /* dwCreationDisposition */ OPEN_ALWAYS,
          /* dwFlagsAndAttributes */ FILE_ATTRIBUTE_NORMAL,
          /* hTemplateFile */ NULL);

      if (stderr_handle == INVALID_HANDLE_VALUE) {
        DWORD err_code = GetLastError();
        result->error_ = bazel::windows::MakeErrorMessage(
            WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
        return PtrAsJlong(result);
      }
      // stderr_process != stdout_process, so set its handle, so the AutoHandle
      // d'tor will close it
      stderr_process = stderr_handle;
    }
  } else {
    if (!CreatePipe(&result->stderr_.handle_, &stderr_handle, &sa, 0)) {
      DWORD err_code = GetLastError();
      result->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
      return PtrAsJlong(result);
    }
    stderr_process = stderr_handle;
  }

  // MDSN says that the default for job objects is that breakaway is not
  // allowed. Thus, we don't need to do any more setup here.
  HANDLE job = CreateJobObject(NULL, NULL);
  if (job == NULL) {
    DWORD err_code = GetLastError();
    result->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
    return PtrAsJlong(result);
  }

  result->job_ = job;

  job_info.BasicLimitInformation.LimitFlags =
      JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
  if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation,
                               &job_info, sizeof(job_info))) {
    DWORD err_code = GetLastError();
    result->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
    return PtrAsJlong(result);
  }

  startup_info.cb = sizeof(STARTUPINFOW);
  startup_info.hStdInput = stdin_process;
  startup_info.hStdOutput = stdout_process;
  startup_info.hStdError = stderr_handle;
  startup_info.dwFlags |= STARTF_USESTDHANDLES;

  HANDLE handlesToInherit[3] = {stdin_process, stdout_process, stderr_handle};
  std::wstring err_msg(CreateProcessWithExplicitHandles(
      /* lpCommandLine */ mutable_commandline.get(),
      /* lpEnvironment */ env_map.ptr(),
      /* lpCurrentDirectory */ cwd.empty() ? nullptr : cwd.c_str(),
      /* lpStartupInfo */ &startup_info,
      /* lpProcessInformation */ &process_info,
      /* cHandlesToInherit */ (stderr_handle == stdout_process) ? 2 : 3,
      /* handlesToInherit */ handlesToInherit));

  if (!err_msg.empty()) {
    result->error_ = err_msg;
    return PtrAsJlong(result);
  }

  result->pid_ = process_info.dwProcessId;
  result->process_ = process_info.hProcess;
  thread = process_info.hThread;

  if (!AssignProcessToJobObject(result->job_, result->process_)) {
    BOOL is_in_job = false;
    if (IsProcessInJob(result->process_, NULL, &is_in_job) && is_in_job &&
        !NestedJobsSupported()) {
      // We are on a pre-Windows 8 system and the Bazel is already in a job.
      // We can't create nested jobs, so just revert to TerminateProcess() and
      // hope for the best. In batch mode, the launcher puts Bazel in a job so
      // that will take care of cleanup once the command finishes.
      CloseHandle(result->job_);
      result->job_ = INVALID_HANDLE_VALUE;
    } else {
      DWORD err_code = GetLastError();
      result->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
      return PtrAsJlong(result);
    }
  }

  // Now that we put the process in a new job object, we can start executing it
  if (ResumeThread(thread) == -1) {
    DWORD err_code = GetLastError();
    result->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeCreateProcess", wpath, err_code);
    return PtrAsJlong(result);
  }

  result->error_ = L"";
  return PtrAsJlong(result);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeWriteStdin(
    JNIEnv* env, jclass clazz, jlong process_long, jbyteArray java_bytes,
    jint offset, jint length) {
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);

  JavaByteArray bytes(env, java_bytes);
  if (offset < 0 || length <= 0 || offset > bytes.size() - length) {
    process->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeWriteStdin", ToString(process->pid_),
        L"Array index out of bounds");
    return -1;
  }

  DWORD bytes_written;

  if (!::WriteFile(process->stdin_, bytes.ptr() + offset, length,
                   &bytes_written, NULL)) {
    DWORD err_code = GetLastError();
    process->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeWriteStdin", ToString(process->pid_),
        err_code);
    bytes_written = -1;
  }

  process->error_ = L"";
  return bytes_written;
}

extern "C" JNIEXPORT jlong JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetStdout(
    JNIEnv* env, jclass clazz, jlong process_long) {
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
  return PtrAsJlong(&process->stdout_);
}

extern "C" JNIEXPORT jlong JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetStderr(
    JNIEnv* env, jclass clazz, jlong process_long) {
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
  return PtrAsJlong(&process->stderr_);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeReadStream(
    JNIEnv* env, jclass clazz, jlong stream_long, jbyteArray java_bytes,
    jint offset, jint length) {
  NativeOutputStream* stream =
      reinterpret_cast<NativeOutputStream*>(stream_long);

  JavaByteArray bytes(env, java_bytes);
  if (offset < 0 || length <= 0 || offset > bytes.size() - length) {
    stream->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeReadStream", L"",
        L"Array index out of bounds");
    return -1;
  }

  if (stream->handle_ == INVALID_HANDLE_VALUE || stream->closed_.load()) {
    stream->error_ = L"";
    return 0;
  }

  DWORD bytes_read;
  if (!::ReadFile(stream->handle_, bytes.ptr() + offset, length, &bytes_read,
                  NULL)) {
    // Check if either the other end closed the pipe or we did it with
    // NativeOutputStream.close() . In the latter case, we'll get a "system
    // call interrupted" error.
    if (GetLastError() == ERROR_BROKEN_PIPE || stream->closed_.load()) {
      // End of file.
      stream->error_ = L"";
      bytes_read = 0;
    } else {
      DWORD err_code = GetLastError();
      stream->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeReadStream", L"", err_code);
      bytes_read = -1;
    }
  } else {
    stream->error_ = L"";
  }

  return bytes_read;
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetExitCode(
    JNIEnv* env, jclass clazz, jlong process_long) {
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
  DWORD exit_code;
  if (!GetExitCodeProcess(process->process_, &exit_code)) {
    DWORD err_code = GetLastError();
    process->error_ = bazel::windows::MakeErrorMessage(
        WSTR(__FILE__), __LINE__, L"nativeGetExitCode", ToString(process->pid_),
        err_code);
    return -1;
  }

  return exit_code;
}

// return values:
// 0: Wait completed successfully
// 1: Timeout
// 2: Wait returned with an error
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeWaitFor(
    JNIEnv* env, jclass clazz, jlong process_long, jlong java_timeout) {
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
  HANDLE handles[1] = {process->process_};
  DWORD win32_timeout = java_timeout < 0 ? INFINITE : java_timeout;
  jint result;
  switch (WaitForMultipleObjects(1, handles, FALSE, win32_timeout)) {
    case 0:
      result = 0;
      break;

    case WAIT_TIMEOUT:
      result = 1;
      break;

    case WAIT_FAILED:
      result = 2;
      break;

    default:
      DWORD err_code = GetLastError();
      process->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeWaitFor", ToString(process->pid_),
          err_code);
      break;
  }

  if (process->stdin_ != INVALID_HANDLE_VALUE) {
    CloseHandle(process->stdin_);
    process->stdin_ = INVALID_HANDLE_VALUE;
  }

  return result;
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetProcessPid(
    JNIEnv* env, jclass clazz, jlong process_long) {
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
  process->error_ = L"";
  return GetProcessId(process->process_);  // MSDN says that this cannot fail
}

extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeTerminate(
    JNIEnv* env, jclass clazz, jlong process_long) {
  static const UINT exit_code = 130;  // 128 + SIGINT, like on Linux
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);

  if (process->job_ != INVALID_HANDLE_VALUE) {
    if (!TerminateJobObject(process->job_, exit_code)) {
      DWORD err_code = GetLastError();
      process->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeTerminate", ToString(process->pid_),
          err_code);
      return JNI_FALSE;
    }
  } else if (process->process_ != INVALID_HANDLE_VALUE) {
    if (!TerminateProcess(process->process_, exit_code)) {
      DWORD err_code = GetLastError();
      process->error_ = bazel::windows::MakeErrorMessage(
          WSTR(__FILE__), __LINE__, L"nativeTerminate", ToString(process->pid_),
          err_code);
      return JNI_FALSE;
    }
  }

  process->error_ = L"";
  return JNI_TRUE;
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeDeleteProcess(
    JNIEnv* env, jclass clazz, jlong process_long) {
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);

  if (process->stdin_ != INVALID_HANDLE_VALUE) {
    CloseHandle(process->stdin_);
  }

  process->stdout_.close();
  process->stderr_.close();

  if (process->process_ != INVALID_HANDLE_VALUE) {
    CloseHandle(process->process_);
  }

  if (process->job_ != INVALID_HANDLE_VALUE) {
    CloseHandle(process->job_);
  }

  delete process;
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeCloseStream(
    JNIEnv* env, jclass clazz, jlong stream_long) {
  NativeOutputStream* stream =
      reinterpret_cast<NativeOutputStream*>(stream_long);
  stream->close();
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeProcessGetLastError(
    JNIEnv* env, jclass clazz, jlong process_long) {
  NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
  jstring result =
      env->NewString(reinterpret_cast<const jchar*>(process->error_.c_str()),
                     process->error_.size());
  process->error_ = L"";
  return result;
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeStreamGetLastError(
    JNIEnv* env, jclass clazz, jlong stream_long) {
  NativeOutputStream* stream =
      reinterpret_cast<NativeOutputStream*>(stream_long);
  jstring result =
      env->NewString(reinterpret_cast<const jchar*>(stream->error_.c_str()),
                     stream->error_.size());
  stream->error_ = L"";
  return result;
}
