// 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.
/// ```dart
/// var duration = const Duration(seconds: 5);
/// print('Start sleeping');
/// sleep(duration);
/// print('5 seconds has passed');
/// ```
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";
  }
}
