// Copyright (c) 2014, 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 int _getExitCode();
  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.
 *
 * While debugging, the VM will not respect the `--pause-isolates-on-exit`
 * flag if [exit] is called as invoking this method causes the Dart VM
 * process to shutdown immediately. To properly break on exit, consider
 * calling [debugger] from `dart:developer` or [Isolate.pause] from
 * `dart:isolate` on [Isolate.current] to pause the isolate before
 * invoking [exit].
 *
 * The handling of exit codes is platform specific.
 *
 * On Linux and OS X 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) {
  ArgumentError.checkNotNull(code, "code");
  if (!_EmbedderConfig._mayExit) {
    throw new UnsupportedError(
        "This embedder disallows calling dart:io's exit()");
  }
  _ProcessUtils._exit(code);
}

/**
 * Set the 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.
 *
 * Default value is `0`.
 *
 * See [exit] for more information on how to chose a value for the
 * exit code.
 */
void set exitCode(int code) {
  ArgumentError.checkNotNull(code, "code");
  _ProcessUtils._setExitCode(code);
}

/**
 * Get the 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.
 */
int get exitCode => _ProcessUtils._getExitCode();

/**
 * 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");
  }
  if (!_EmbedderConfig._maySleep) {
    throw new UnsupportedError(
        "This embedder disallows calling dart:io's sleep()");
  }
  _ProcessUtils._sleep(milliseconds);
}

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

/**
 * [ProcessInfo] provides methods for retrieving information about the
 * current process.
 */
class ProcessInfo {
  /**
   * The current resident set size of memory for the process.
   *
   * Note that the meaning of this field is platform dependent. For example,
   * some memory accounted for here may be shared with other processes, or if
   * the same page is mapped into a process's address space, it may be counted
   * twice.
   */
  external static int get currentRss;

  /**
   * The high-watermark in bytes for the resident set size of memory for the
   * process.
   *
   * Note that the meaning of this field is platform dependent. For example,
   * some memory accounted for here may be shared with other processes, or if
   * the same page is mapped into a process's address space, it may be counted
   * twice.
   */
  external static int get maxRss;
}

/**
 * Modes for running a new process.
 */
class ProcessStartMode {
  /// Normal child process.
  static const normal = const ProcessStartMode._internal(0);
  @Deprecated("Use normal instead")
  static const NORMAL = normal;

  /// Stdio handles are inherited by the child process.
  static const inheritStdio = const ProcessStartMode._internal(1);
  @Deprecated("Use inheritStdio instead")
  static const INHERIT_STDIO = inheritStdio;

  /// Detached child process with no open communication channel.
  static const detached = const ProcessStartMode._internal(2);
  @Deprecated("Use detached instead")
  static const DETACHED = detached;

  /// Detached child process with stdin, stdout and stderr still open
  /// for communication with the child.
  static const detachedWithStdio = const ProcessStartMode._internal(3);
  @Deprecated("Use detachedWithStdio instead")
  static const DETACHED_WITH_STDIO = detachedWithStdio;

  static List<ProcessStartMode> get values => const <ProcessStartMode>[
        normal,
        inheritStdio,
        detached,
        detachedWithStdio
      ];
  String toString() =>
      const ["normal", "inheritStdio", "detached", "detachedWithStdio"][_mode];

  final int _mode;
  const ProcessStartMode._internal(this._mode);
}

/**
 * The means to execute a program.
 *
 * Use the static [start] and [run] methods to start a new process.
 * The run method executes the process non-interactively to completion.
 * In contrast, the start method allows your code to interact with the
 * running process.
 *
 * ## Start a process with the run method
 *
 * The following code sample uses the run method to create a process
 * that runs the UNIX command `ls`, which lists the contents of a directory.
 * The run method completes with a [ProcessResult] object when the process
 * terminates. This provides access to the output and exit code from the
 * process. The run method does not return a Process object; this prevents your
 * code from interacting with the running process.
 *
 *     import 'dart:io';
 *
 *     main() {
 *       // List all files in the current directory in UNIX-like systems.
 *       Process.run('ls', ['-l']).then((ProcessResult results) {
 *         print(results.stdout);
 *       });
 *     }
 *
 * ## Start a process with the start method
 *
 * The following example uses start to create the process.
 * The start method returns a [Future] for a Process object.
 * When the future completes the process is started and
 * your code can interact with the
 * Process: writing to stdin, listening to stdout, and so on.
 *
 * The following sample starts the UNIX `cat` utility, which when given no
 * command-line arguments, echos its input.
 * The program writes to the process's standard input stream
 * and prints data from its standard output stream.
 *
 *     import 'dart:io';
 *     import 'dart:convert';
 *
 *     main() {
 *       Process.start('cat', []).then((Process process) {
 *         process.stdout
 *             .transform(utf8.decoder)
 *             .listen((data) { print(data); });
 *         process.stdin.writeln('Hello, world!');
 *         process.stdin.writeln('Hello, galaxy!');
 *         process.stdin.writeln('Hello, universe!');
 *       });
 *     }
 *
 * ## Standard I/O streams
 *
 * As seen in the previous code sample, you can interact with the Process's
 * standard output stream through the getter [stdout],
 * and you can interact with the Process's standard input stream through
 * the getter [stdin].
 * In addition, Process provides a getter [stderr] for using the Process's
 * standard error stream.
 *
 * A Process's streams are distinct from the top-level streams
 * for the current program.
 *
 * ## Exit codes
 *
 * Call the [exitCode] method to get the exit code of the process.
 * The exit code indicates whether the program terminated successfully
 * (usually indicated with an exit code of 0) or with an error.
 *
 * If the start method is used, the exitCode is available through a future
 * on the Process object (as shown in the example below).
 * If the run method is used, the exitCode is available
 * through a getter on the ProcessResult instance.
 *
 *     import 'dart:io';
 *
 *     main() {
 *       Process.start('ls', ['-l']).then((process) {
 *         // Get the exit code from the new process.
 *         process.exitCode.then((exitCode) {
 *           print('exit code: $exitCode');
 *         });
 *       });
 *     }
 *
 * ## Other resources
 *
 * [Dart by Example](https://www.dartlang.org/dart-by-example/#dart-io-and-command-line-apps)
 * provides additional task-oriented code samples that show how to use
 * various API from the [dart:io] library.
 */
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 OS X 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`.
   *
   * There is no guarantee that [stdout] and [stderr] have finished reporting
   * the buffered output of the process when the returned future completes.
   * To be sure that all output is captured,
   * wait for the done event on the streams.
   */
  Future<int> get 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 OS X, [:/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 released 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);
   *     });
   *
   * If [mode] is [ProcessStartMode.normal] (the default) a child
   * process will be started with `stdin`, `stdout` and `stderr`
   * connected.
   *
   * If `mode` is [ProcessStartMode.detached] a detached process will
   * be created. A detached process has no connection to its parent,
   * and can keep running on its own when the parent dies. The only
   * information available from a detached process is its `pid`. There
   * is no connection to its `stdin`, `stdout` or `stderr`, nor will
   * the process' exit code become available when it terminates.
   *
   * If `mode` is [ProcessStartMode.detachedWithStdio] a detached
   * process will be created where the `stdin`, `stdout` and `stderr`
   * are connected. The creator can communicate with the child through
   * these. The detached process will keep running even if these
   * communication channels are closed. The process' exit code will
   * not become available when it terminated.
   *
   * The default value for `mode` is `ProcessStartMode.normal`.
   */
  external static Future<Process> start(
      String executable, List<String> arguments,
      {String workingDirectory,
      Map<String, String> environment,
      bool includeParentEnvironment: true,
      bool runInShell: false,
      ProcessStartMode mode: ProcessStartMode.normal});

  /**
   * 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 OS X, `/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 [systemEncoding]. 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: systemEncoding,
      Encoding stderrEncoding: systemEncoding});

  /**
   * 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: systemEncoding,
      Encoding stderrEncoding: systemEncoding});

  /**
   * Kills the process with id [pid].
   *
   * Where possible, sends the [signal] to the process with id
   * `pid`. This includes Linux and OS X. The default signal is
   * [ProcessSignal.sigterm] which will normally terminate the
   * process.
   *
   * On platforms without signal support, including Windows, the call
   * just terminates the process with id `pid` in a platform specific
   * way, and the `signal` parameter is ignored.
   *
   * Returns `true` if the signal is successfully delivered to the
   * process. Otherwise the signal could not be sent, usually meaning
   * that the process is already dead.
   */
  external static bool killPid(int pid,
      [ProcessSignal signal = ProcessSignal.sigterm]);

  /**
   * 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;

  /**
   * Kills the process.
   *
   * Where possible, sends the [signal] to the process. This includes
   * Linux and OS X. The default signal is [ProcessSignal.sigterm]
   * which will normally terminate the process.
   *
   * On platforms without signal support, including Windows, the call
   * just terminates the process in a platform specific way, and the
   * `signal` parameter is ignored.
   *
   * Returns `true` if the signal is successfully delivered to the
   * process. 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] or [Process.runSync].
 */
class ProcessResult {
  /**
   * Exit code for the process.
   *
   * See [Process.exitCode] for more information in the exit code
   * value.
   */
  final int exitCode;

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

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

  /**
   * Process id of the process.
   */
  final int pid;

  ProcessResult(this.pid, this.exitCode, this.stdout, this.stderr);
}

/**
 * On Posix systems, [ProcessSignal] is used to send a specific signal
 * to a child process, see [:Process.kill:].
 *
 * Some [ProcessSignal]s can also be watched, as a way to intercept the default
 * signal handler and implement another. See [ProcessSignal.watch] for more
 * information.
 */
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");

  @Deprecated("Use sighup instead")
  static const ProcessSignal SIGHUP = sighup;
  @Deprecated("Use sigint instead")
  static const ProcessSignal SIGINT = sigint;
  @Deprecated("Use sigquit instead")
  static const ProcessSignal SIGQUIT = sigquit;
  @Deprecated("Use sigill instead")
  static const ProcessSignal SIGILL = sigill;
  @Deprecated("Use sigtrap instead")
  static const ProcessSignal SIGTRAP = sigtrap;
  @Deprecated("Use sigabrt instead")
  static const ProcessSignal SIGABRT = sigabrt;
  @Deprecated("Use sigbus instead")
  static const ProcessSignal SIGBUS = sigbus;
  @Deprecated("Use sigfpe instead")
  static const ProcessSignal SIGFPE = sigfpe;
  @Deprecated("Use sigkill instead")
  static const ProcessSignal SIGKILL = sigkill;
  @Deprecated("Use sigusr1 instead")
  static const ProcessSignal SIGUSR1 = sigusr1;
  @Deprecated("Use sigsegv instead")
  static const ProcessSignal SIGSEGV = sigsegv;
  @Deprecated("Use sigusr2 instead")
  static const ProcessSignal SIGUSR2 = sigusr2;
  @Deprecated("Use sigpipe instead")
  static const ProcessSignal SIGPIPE = sigpipe;
  @Deprecated("Use sigalrm instead")
  static const ProcessSignal SIGALRM = sigalrm;
  @Deprecated("Use sigterm instead")
  static const ProcessSignal SIGTERM = sigterm;
  @Deprecated("Use sigchld instead")
  static const ProcessSignal SIGCHLD = sigchld;
  @Deprecated("Use sigcont instead")
  static const ProcessSignal SIGCONT = sigcont;
  @Deprecated("Use sigstop instead")
  static const ProcessSignal SIGSTOP = sigstop;
  @Deprecated("Use sigtstp instead")
  static const ProcessSignal SIGTSTP = sigtstp;
  @Deprecated("Use sigttin instead")
  static const ProcessSignal SIGTTIN = sigttin;
  @Deprecated("Use sigttou instead")
  static const ProcessSignal SIGTTOU = sigttou;
  @Deprecated("Use sigurg instead")
  static const ProcessSignal SIGURG = sigurg;
  @Deprecated("Use sigxcpu instead")
  static const ProcessSignal SIGXCPU = sigxcpu;
  @Deprecated("Use sigxfsz instead")
  static const ProcessSignal SIGXFSZ = sigxfsz;
  @Deprecated("Use sigvtalrm instead")
  static const ProcessSignal SIGVTALRM = sigvtalrm;
  @Deprecated("Use sigprof instead")
  static const ProcessSignal SIGPROF = sigprof;
  @Deprecated("Use sigwinch instead")
  static const ProcessSignal SIGWINCH = sigwinch;
  @Deprecated("Use sigpoll instead")
  static const ProcessSignal SIGPOLL = sigpoll;
  @Deprecated("Use sigsys instead")
  static const ProcessSignal SIGSYS = 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]. Signal sent by e.g. CTRL-C.
   *   * [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.
   *
   * A signal can be watched multiple times, from multiple isolates, where all
   * callbacks are invoked when signaled, in no specific order.
   */
  Stream<ProcessSignal> watch() => _ProcessUtils._watchSignal(this);
}

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

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

  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";
  }
}
