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

package com.google.devtools.build.lib.windows;

import com.google.devtools.build.lib.jni.JniLoader;

/** Process management on Windows. */
public class WindowsProcesses {
  public static final long INVALID = -1;

  static {
    JniLoader.loadJni();
  }

  private WindowsProcesses() {
    // Prevent construction
  }

  /**
   * Creates a process with the specified Windows command line.
   *
   * <p>Appropriately quoting arguments is the responsibility of the caller.
   *
   * @param argv0 the binary to run; must be unquoted; must be either an absolute, normalized
   *     Windows path with a drive letter (e.g. "c:\foo\bar app.exe") or a single file name (e.g.
   *     "foo app.exe")
   * @param argvRest the rest of the command line, i.e. argv[1:] (needs to be quoted Windows style)
   * @param env the environment of the new process. null means inherit that of the Bazel server
   * @param cwd the working directory of the new process. If null, the same as that of the current
   *     process.
   * @param stdoutFile the file the stdout should be redirected to. If null, {@link #getStdout} will
   *     work.
   * @param stderrFile the file the stdout should be redirected to. If null, {@link #getStderr} will
   *     work.
   * @param redirectErrorStream whether we merge the process's standard error and standard output.
   * @return the opaque identifier of the created process
   */
  public static native long createProcess(
      String argv0,
      String argvRest,
      byte[] env,
      String cwd,
      String stdoutFile,
      String stderrFile,
      boolean redirectErrorStream);

  public static long createProcess(
      String argv0, String argvRest, byte[] env, String cwd, String stdoutFile, String stderrFile) {
    return createProcess(argv0, argvRest, env, cwd, stdoutFile, stderrFile, false);
  }

  /**
   * Writes data from the given array to the stdin of the specified process.
   *
   * <p>Blocks until either some data was written or the process is terminated.
   *
   * @return the number of bytes written
   */
  public static native int writeStdin(long process, byte[] bytes, int offset, int length);

  /** Returns an opaque identifier of stdout stream for the process. */
  public static native long getStdout(long process);

  /** Returns an opaque identifier of stderr stream for the process. */
  public static native long getStderr(long process);

  /**
   * Reads data from the stream into the given array. {@code stream} should come from {@link
   * #getStdout(long)} or {@link #getStderr(long)}.
   *
   * <p>Blocks until either some data was read or the process is terminated.
   *
   * @return the number of bytes read, 0 on EOF, or -1 if there was an error.
   */
  public static native int readStream(long stream, byte[] bytes, int offset, int length);

  /**
   * Waits until the given process terminates. If timeout is non-negative, it indicates the number
   * of milliseconds before the call times out.
   *
   * <p>Return values:
   * <li>0: Process finished
   * <li>1: Timeout
   * <li>2: Something went wrong
   */
  public static native int waitFor(long process, long timeout);

  /**
   * Returns the exit code of the process. Throws {@code IllegalStateException} if something goes
   * wrong.
   */
  public static native int getExitCode(long process);

  /** Returns the process ID of the given process or -1 if there was an error. */
  public static native int getProcessPid(long process);

  /** Terminates the given process. Returns true if the termination was successful. */
  public static native boolean terminate(long process);

  /**
   * Releases the native data structures associated with the process.
   *
   * <p>Calling any other method on the same process after this call will result in the JVM crashing
   * or worse.
   */
  public static native void deleteProcess(long process);

  /**
   * Closes the stream
   *
   * @param stream should come from {@link #getStdout(long)} or {@link #getStderr(long)}.
   */
  public static native void closeStream(long stream);

  /**
   * Returns a string representation of the last error caused by any call on the given process or
   * the empty string if the last operation was successful.
   *
   * <p>Does <b>NOT</b> terminate the process if it is still running.
   *
   * <p>After this call returns, subsequent calls will return the empty string if there was no
   * failed operation in between.
   */
  public static native String processGetLastError(long process);

  public static native String streamGetLastError(long process);

  /** Returns the PID of the current process. */
  public static native int getpid();
}
