// 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 Never _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 nor execute
/// `finally` blocks. 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.
Never 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);

/// 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.
/// ```dart
/// import 'dart:io';
///
/// main() async {
///   // List all files in the current directory in UNIX-like systems.
///   var result = await Process.run('ls', ['-l']);
///   print(result.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.
/// ```dart
/// import 'dart:io';
/// import 'dart:convert';
///
/// main() async {
///   var process = await Process.start('cat', []);
///   process.stdout
///       .transform(utf8.decoder)
///       .forEach(print);
///   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.
/// ```dart
/// import 'dart:io';
///
/// main() async {
///   var process = await Process.start('ls', ['-l']);
///   var exitCode = await process.exitCode;
///   print('exit code: $exitCode');
/// }
/// ```
abstract class Process {
  /// 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.
  /// ```dart
  /// var process = await Process.start('grep', ['-i', 'main', 'test.dart']);
  /// 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.
  /// ```dart
  /// var result = await Process.run('grep', ['-i', 'main', 'test.dart']);
  /// 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]);

  /// The standard output stream of the process as a `Stream`.
  Stream<List<int>> get stdout;

  /// The standard error stream of the process as a `Stream`.
  Stream<List<int>> get stderr;

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

  /// 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]);
}

/// 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 {
  /// The executable provided for the process.
  final String executable;

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

  /// The system message for the process exception, if any.
  ///
  /// The empty string if no message was available.
  final String message;

  /// The OS error code for the process exception, if any.
  ///
  /// The value is zero if no OS error code was available.
  final int errorCode;

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