// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.io;

// TODO(ager): The only reason for this class is that we
// cannot patch a top-level at this point.
class _ProcessUtils {
  external static void _exit(int status);
  external static void _setExitCode(int status);
  external static void _sleep(int millis);
  external static int _pid(Process process);
  external static Stream<ProcessSignal> _watchSignal(ProcessSignal signal);
}

/**
 * Exit the Dart VM process immediately with the given exit code.
 *
 * This does not wait for any asynchronous operations to terminate. Using
 * [exit] is therefore very likely to lose data.
 *
 * The handling of exit codes is platform specific.
 *
 * On Linux and Mac OS an exit code for normal termination will always
 * be in the range [0..255]. If an exit code outside this range is
 * set the actual exit code will be the lower 8 bits masked off and
 * treated as an unsigned value. E.g. using an exit code of -1 will
 * result in an actual exit code of 255 being reported.
 *
 * On Windows the exit code can be set to any 32-bit value. However
 * some of these values are reserved for reporting system errors like
 * crashes.
 *
 * Besides this the Dart executable itself uses an exit code of `254`
 * for reporting compile time errors and an exit code of `255` for
 * reporting runtime error (unhandled exception).
 *
 * Due to these facts it is recommended to only use exit codes in the
 * range [0..127] for communicating the result of running a Dart
 * program to the surrounding environment. This will avoid any
 * cross-platform issues.
 */
void exit(int code) {
  if (code is !int) {
    throw new ArgumentError("Integer value for exit code expected");
  }
  _ProcessUtils._exit(code);
}

/**
 * Global exit code for the Dart VM.
 *
 * The exit code is global for the Dart VM and the last assignment to
 * exitCode from any isolate determines the exit code of the Dart VM
 * on normal termination.
 *
 * See [exit] for more information on how to chose a value for the
 * exit code.
 */
set exitCode(int code) {
  if (code is !int) {
    throw new ArgumentError("Integer value for exit code expected");
  }
  _ProcessUtils._setExitCode(code);
}

/**
 * Sleep for the duration specified in [duration].
 *
 * Use this with care, as no asynchronous operations can be processed
 * in a isolate while it is blocked in a [sleep] call.
 */
void sleep(Duration duration) {
  int milliseconds = duration.inMilliseconds;
  if (milliseconds < 0) {
    throw new ArgumentError("sleep: duration cannot be negative");
  }
  _ProcessUtils._sleep(milliseconds);
}

/**
 * Returns the PID of the current process.
 */
int get pid => _ProcessUtils._pid(null);

/**
 * [Process] is used to start new processes using the static
 * [start] and [run] methods.
 */
abstract class Process {
  /**
   * Returns a [:Future:] which completes with the exit code of the process
   * when the process completes.
   *
   * The handling of exit codes is platform specific.
   *
   * On Linux and Mac a normal exit code will be a positive value in
   * the range [0..255]. If the process was terminated due to a signal
   * the exit code will be a negative value in the range [-255..-1],
   * where the absolute value of the exit code is the signal
   * number. For example, if a process crashes due to a segmentation
   * violation the exit code will be -11, as the signal SIGSEGV has the
   * number 11.
   *
   * On Windows a process can report any 32-bit value as an exit
   * code. When returning the exit code this exit code is turned into
   * a signed value. Some special values are used to report
   * termination due to some system event. E.g. if a process crashes
   * due to an access violation the 32-bit exit code is `0xc0000005`,
   * which will be returned as the negative number `-1073741819`. To
   * get the original 32-bit value use `(0x100000000 + exitCode) &
   * 0xffffffff`.
   */
  Future<int> exitCode;

  /**
   * Starts a process running the [executable] with the specified
   * [arguments]. Returns a [:Future<Process>:] that completes with a
   * Process instance when the process has been successfully
   * started. That [Process] object can be used to interact with the
   * process. If the process cannot be started the returned [Future]
   * completes with an exception.
   *
   * Use [workingDirectory] to set the working directory for the process. Note
   * that the change of directory occurs before executing the process on some
   * platforms, which may have impact when using relative paths for the
   * executable and the arguments.
   *
   * Use [environment] to set the environment variables for the process. If not
   * set the environment of the parent process is inherited. Currently, only
   * US-ASCII environment variables are supported and errors are likely to occur
   * if an environment variable with code-points outside the US-ASCII range is
   * passed in.
   *
   * If [includeParentEnvironment] is `true`, the process's environment will
   * include the parent process's environment, with [environment] taking
   * precedence. Default is `true`.
   *
   * If [runInShell] is true, the process will be spawned through a system
   * shell. On Linux and Mac OS, [:/bin/sh:] is used, while
   * [:%WINDIR%\system32\cmd.exe:] is used on Windows.
   *
   * Users must read all data coming on the [stdout] and [stderr]
   * streams of processes started with [:Process.start:]. If the user
   * does not read all data on the streams the underlying system
   * resources will not be freed since there is still pending data.
   *
   * The following code uses `Process.start` to grep for `main` in the
   * file `test.dart` on Linux.
   *
   *     Process.start('grep', ['-i', 'main', 'test.dart']).then((process) {
   *       stdout.addStream(process.stdout);
   *       stderr.addStream(process.stderr);
   *     });
   */
  external static Future<Process> start(
      String executable,
      List<String> arguments,
      {String workingDirectory,
       Map<String, String> environment,
       bool includeParentEnvironment: true,
       bool runInShell: false});

  /**
   * Starts a process and runs it non-interactively to completion. The
   * process run is [executable] with the specified [arguments].
   *
   * Use [workingDirectory] to set the working directory for the process. Note
   * that the change of directory occurs before executing the process on some
   * platforms, which may have impact when using relative paths for the
   * executable and the arguments.
   *
   * Use [environment] to set the environment variables for the process. If not
   * set the environment of the parent process is inherited. Currently, only
   * US-ASCII environment variables are supported and errors are likely to occur
   * if an environment variable with code-points outside the US-ASCII range is
   * passed in.
   *
   * If [includeParentEnvironment] is `true`, the process's environment will
   * include the parent process's environment, with [environment] taking
   * precedence. Default is `true`.
   *
   * If [runInShell] is true, the process will be spawned through a system
   * shell. On Linux and Mac OS, `/bin/sh` is used, while
   * `%WINDIR%\system32\cmd.exe` is used on Windows.
   *
   * The encoding used for decoding `stdout` and `stderr` into text is
   * controlled through [stdoutEncoding] and [stderrEncoding]. The
   * default encoding is [SYSTEM_ENCODING]. If `null` is used no
   * decoding will happen and the [ProcessResult] will hold binary
   * data.
   *
   * Returns a `Future<ProcessResult>` that completes with the
   * result of running the process, i.e., exit code, standard out and
   * standard in.
   *
   * The following code uses `Process.run` to grep for `main` in the
   * file `test.dart` on Linux.
   *
   *     Process.run('grep', ['-i', 'main', 'test.dart']).then((result) {
   *       stdout.write(result.stdout);
   *       stderr.write(result.stderr);
   *     });
   */
  external static Future<ProcessResult> run(
      String executable,
      List<String> arguments,
      {String workingDirectory,
       Map<String, String> environment,
       bool includeParentEnvironment: true,
       bool runInShell: false,
       Encoding stdoutEncoding: SYSTEM_ENCODING,
       Encoding stderrEncoding: SYSTEM_ENCODING});


  /**
   * Starts a process and runs it to completion. This is a synchronous
   * call and will block until the child process terminates.
   *
   * The arguments are the same as for `Process.run`.
   *
   * Returns a `ProcessResult` with the result of running the process,
   * i.e., exit code, standard out and standard in.
   */
  external static ProcessResult runSync(
      String executable,
      List<String> arguments,
      {String workingDirectory,
       Map<String, String> environment,
       bool includeParentEnvironment: true,
       bool runInShell: false,
       Encoding stdoutEncoding: SYSTEM_ENCODING,
       Encoding stderrEncoding: SYSTEM_ENCODING});

  /**
   * Returns the standard output stream of the process as a [:Stream:].
   */
  Stream<List<int>> get stdout;

  /**
   * Returns the standard error stream of the process as a [:Stream:].
   */
  Stream<List<int>> get stderr;

  /**
   * Returns the standard input stream of the process as an [IOSink].
   */
  IOSink get stdin;

  /**
   * Returns the process id of the process.
   */
  int get pid;

  /**
   * On Linux and Mac OS, [kill] sends [signal] to the process. When the process
   * terminates as a result of calling [kill], the value for [exitCode] may be a
   * negative number corresponding to the provided [signal].
   *
   * On Windows, [kill] kills the process, ignoring the [signal] flag.
   *
   * Returns [:true:] if the signal is successfully sent and process is killed.
   * Otherwise the signal could not be sent, usually meaning that the process is
   * already dead.
   */
  bool kill([ProcessSignal signal = ProcessSignal.SIGTERM]);
}


/**
 * [ProcessResult] represents the result of running a non-interactive
 * process started with [:Process.run:].
 */
abstract class ProcessResult {
  /**
   * Exit code for the process.
   *
   * See [Process.exitCode] for more information in the exit code
   * value.
   */
  int get exitCode;

  /**
   * Standard output from the process. The value used for the
   * `stdoutEncoding` argument to `Process.run` determins the type. If
   * `null` was used this value is of type `List<int> otherwise it is
   * of type `String`.
   */
  get stdout;

  /**
   * Standard error from the process. The value used for the
   * `stderrEncoding` argument to `Process.run` determins the type. If
   * `null` was used this value is of type `List<int>
   * otherwise it is of type `String`.
   */
  get stderr;

  /**
   * Process id from the process.
   */
  int get pid;
}


/**
 * On Posix systems, [ProcessSignal] is used to send a specific signal
 * to a child process, see [:Process.kill:].
 */
class ProcessSignal {
  static const ProcessSignal SIGHUP = const ProcessSignal._(1, "SIGHUP");
  static const ProcessSignal SIGINT = const ProcessSignal._(2, "SIGINT");
  static const ProcessSignal SIGQUIT = const ProcessSignal._(3, "SIGQUIT");
  static const ProcessSignal SIGILL = const ProcessSignal._(4, "SIGILL");
  static const ProcessSignal SIGTRAP = const ProcessSignal._(5, "SIGTRAP");
  static const ProcessSignal SIGABRT = const ProcessSignal._(6, "SIGABRT");
  static const ProcessSignal SIGBUS = const ProcessSignal._(7, "SIGBUS");
  static const ProcessSignal SIGFPE = const ProcessSignal._(8, "SIGFPE");
  static const ProcessSignal SIGKILL = const ProcessSignal._(9, "SIGKILL");
  static const ProcessSignal SIGUSR1 = const ProcessSignal._(10, "SIGUSR1");
  static const ProcessSignal SIGSEGV = const ProcessSignal._(11, "SIGSEGV");
  static const ProcessSignal SIGUSR2 = const ProcessSignal._(12, "SIGUSR2");
  static const ProcessSignal SIGPIPE = const ProcessSignal._(13, "SIGPIPE");
  static const ProcessSignal SIGALRM = const ProcessSignal._(14, "SIGALRM");
  static const ProcessSignal SIGTERM = const ProcessSignal._(15, "SIGTERM");
  static const ProcessSignal SIGCHLD = const ProcessSignal._(17, "SIGCHLD");
  static const ProcessSignal SIGCONT = const ProcessSignal._(18, "SIGCONT");
  static const ProcessSignal SIGSTOP = const ProcessSignal._(19, "SIGSTOP");
  static const ProcessSignal SIGTSTP = const ProcessSignal._(20, "SIGTSTP");
  static const ProcessSignal SIGTTIN = const ProcessSignal._(21, "SIGTTIN");
  static const ProcessSignal SIGTTOU = const ProcessSignal._(22, "SIGTTOU");
  static const ProcessSignal SIGURG = const ProcessSignal._(23, "SIGURG");
  static const ProcessSignal SIGXCPU = const ProcessSignal._(24, "SIGXCPU");
  static const ProcessSignal SIGXFSZ = const ProcessSignal._(25, "SIGXFSZ");
  static const ProcessSignal SIGVTALRM = const ProcessSignal._(26, "SIGVTALRM");
  static const ProcessSignal SIGPROF = const ProcessSignal._(27, "SIGPROF");
  static const ProcessSignal SIGWINCH = const ProcessSignal._(28, "SIGWINCH");
  static const ProcessSignal SIGPOLL = const ProcessSignal._(29, "SIGPOLL");
  static const ProcessSignal SIGSYS = const ProcessSignal._(31, "SIGSYS");

  final int _signalNumber;
  final String _name;

  const ProcessSignal._(this._signalNumber, this._name);

  String toString() => _name;

  /**
   * Watch for process signals.
   *
   * The following [ProcessSignal]s can be listened to:
   *
   *   * [ProcessSignal.SIGHUP].
   *   * [ProcessSignal.SIGINT].
   *   * [ProcessSignal.SIGTERM]. Not available on Windows.
   *   * [ProcessSignal.SIGUSR1]. Not available on Windows.
   *   * [ProcessSignal.SIGUSR2]. Not available on Windows.
   *   * [ProcessSignal.SIGWINCH]. Not available on Windows.
   *
   * Other signals are disallowed, as they may be used by the VM.
   */
  Stream<ProcessSignal> watch() => _ProcessUtils._watchSignal(this);
}


class SignalException implements IOException {
  final String message;
  final osError;

  const SignalException(this.message, [this.osError = null]);

  String toString() {
    var msg = "";
    if (osError != null) {
      msg = ", osError: $osError";
    }
    return "SignalException: $message$msg";
  }
}


class ProcessException implements IOException {
  /**
   * Contains the executable provided for the process.
   */
  final String executable;

  /**
   * Contains the arguments provided for the process.
   */
  final List<String> arguments;

  /**
   * Contains the system message for the process exception if any.
   */
  final String message;

  /**
   * Contains the OS error code for the process exception if any.
   */
  final int errorCode;

  const ProcessException(this.executable, this.arguments, [this.message = "",
                         this.errorCode = 0]);
  String toString() {
    var msg = (message == null) ? 'OS error code: $errorCode' : message;
    var args = arguments.join(' ');
    return "ProcessException: $msg\n  Command: $executable $args";
  }
}
