// 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 "common_patch.dart";

@patch
class _WindowsCodePageDecoder {
  @patch
  @pragma("vm:external-name", "SystemEncodingToString")
  external static String _decodeBytes(List<int> bytes);
}

@patch
class _WindowsCodePageEncoder {
  @patch
  @pragma("vm:external-name", "StringToSystemEncoding")
  external static List<int> _encodeString(String string);
}

@patch
class Process {
  @patch
  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,
  }) {
    _ProcessImpl process = _ProcessImpl(
      executable,
      arguments,
      workingDirectory,
      environment,
      includeParentEnvironment,
      runInShell,
      mode,
    );
    return process._start();
  }

  @patch
  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,
  }) {
    return _runNonInteractiveProcess(
      executable,
      arguments,
      workingDirectory,
      environment,
      includeParentEnvironment,
      runInShell,
      stdoutEncoding,
      stderrEncoding,
    );
  }

  @patch
  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,
  }) {
    return _runNonInteractiveProcessSync(
      executable,
      arguments,
      workingDirectory,
      environment,
      includeParentEnvironment,
      runInShell,
      stdoutEncoding,
      stderrEncoding,
    );
  }

  @patch
  static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) {
    // TODO(40614): Remove once non-nullability is sound.
    ArgumentError.checkNotNull(signal, "signal");
    return _ProcessUtils._killPid(pid, signal.signalNumber);
  }
}

List<_SignalController?> _signalControllers = List.filled(32, null);

class _SignalController {
  final ProcessSignal signal;

  final _controller = StreamController<ProcessSignal>.broadcast();
  var _id;

  _SignalController(this.signal) {
    _controller
      ..onListen = _listen
      ..onCancel = _cancel;
  }

  Stream<ProcessSignal> get stream => _controller.stream;

  void _listen() {
    var id = _setSignalHandler(signal.signalNumber);
    if (id is! int) {
      _controller.addError(SignalException("Failed to listen for $signal", id));
      return;
    }
    _id = id;
    var socket = _RawSocket(_NativeSocket._watchSignal(id));
    socket.listen((event) {
      if (event == RawSocketEvent.read) {
        var bytes = socket.read()!;
        for (int i = 0; i < bytes.length; i++) {
          _controller.add(signal);
        }
      }
    });
  }

  void _cancel() {
    if (_id != null) {
      _clearSignalHandler(signal.signalNumber);
      _id = null;
    }
  }

  @pragma("vm:external-name", "Process_SetSignalHandler")
  external static _setSignalHandler(int signal);
  @pragma("vm:external-name", "Process_ClearSignalHandler")
  external static void _clearSignalHandler(int signal);
}

@pragma("vm:entry-point", "call")
Function _getWatchSignalInternal() => _ProcessUtils._watchSignalInternal;

@patch
class _ProcessUtils {
  @patch
  @pragma("vm:external-name", "Process_Exit")
  external static Never _exit(int status);
  @patch
  @pragma("vm:external-name", "Process_SetExitCode")
  external static void _setExitCode(int status);
  @patch
  @pragma("vm:external-name", "Process_GetExitCode")
  external static int _getExitCode();
  @patch
  @pragma("vm:external-name", "Process_Sleep")
  external static void _sleep(int millis);
  @patch
  @pragma("vm:external-name", "Process_Pid")
  external static int _pid(Process? process);
  @pragma("vm:external-name", "Process_KillPid")
  external static bool _killPid(int pid, int signal);
  @patch
  static Stream<ProcessSignal> _watchSignal(ProcessSignal signal) {
    if (signal != ProcessSignal.sighup &&
        signal != ProcessSignal.sigint &&
        signal != ProcessSignal.sigterm &&
        (Platform.isWindows ||
            (signal != ProcessSignal.sigusr1 &&
                signal != ProcessSignal.sigusr2 &&
                signal != ProcessSignal.sigwinch))) {
      throw SignalException("Listening for signal $signal is not supported");
    }
    return _watchSignalInternal(signal);
  }

  static Stream<ProcessSignal> _watchSignalInternal(ProcessSignal signal) {
    if (_signalControllers[signal.signalNumber] == null) {
      _signalControllers[signal.signalNumber] = _SignalController(signal);
    }
    return _signalControllers[signal.signalNumber]!.stream;
  }
}

@patch
class ProcessInfo {
  @patch
  static int get maxRss {
    var result = _maxRss();
    if (result is OSError) {
      throw result;
    }
    return result;
  }

  @patch
  static int get currentRss {
    var result = _currentRss();
    if (result is OSError) {
      throw result;
    }
    return result;
  }

  @pragma("vm:external-name", "ProcessInfo_MaxRSS")
  external static _maxRss();
  @pragma("vm:external-name", "ProcessInfo_CurrentRSS")
  external static _currentRss();
}

@pragma("vm:entry-point")
class _ProcessStartStatus {
  @pragma("vm:entry-point", "set")
  int? _errorCode; // Set to OS error code if process start failed.
  @pragma("vm:entry-point", "set")
  String? _errorMessage; // Set to OS error message if process start failed.
}

// The NativeFieldWrapperClass1 can not be used with a mixin, due to missing
// implicit constructor.
base class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {}

base class _ProcessImpl extends _ProcessImplNativeWrapper implements _Process {
  static bool connectedResourceHandler = false;

  _ProcessImpl(
    String path,
    List<String> arguments,
    this._workingDirectory,
    Map<String, String>? environment,
    bool includeParentEnvironment,
    bool runInShell,
    this._mode,
  ) : super() {
    // TODO(40614): Remove once non-nullability is sound.
    ArgumentError.checkNotNull(path, "path");
    ArgumentError.checkNotNull(arguments, "arguments");
    for (int i = 0; i < arguments.length; i++) {
      ArgumentError.checkNotNull(arguments[i], "arguments[]");
    }
    ArgumentError.checkNotNull(_mode, "mode");

    if (!const bool.fromEnvironment("dart.vm.product") &&
        !connectedResourceHandler) {
      registerExtension(
        'ext.dart.io.getSpawnedProcesses',
        _SpawnedProcessResourceInfo.getStartedProcesses,
      );
      registerExtension(
        'ext.dart.io.getSpawnedProcessById',
        _SpawnedProcessResourceInfo.getProcessInfoMapById,
      );
      connectedResourceHandler = true;
    }

    if (runInShell) {
      arguments = _getShellArguments(path, arguments);
      path = _getShellCommand();
    }

    if (Platform.isWindows && path.contains(' ') && !path.contains('"')) {
      // Escape paths that may contain spaces
      // Bug: https://github.com/dart-lang/sdk/issues/37751
      _path = '"$path"';
    } else {
      _path = path;
    }

    _arguments = [
      for (int i = 0; i < arguments.length; i++)
        Platform.isWindows
            ? _windowsArgumentEscape(arguments[i])
            : arguments[i],
    ];

    _environment = [];
    // Ensure that we have a non-null environment.
    environment ??= const {};
    environment.forEach((key, value) {
      _environment.add('$key=$value');
    });
    if (includeParentEnvironment) {
      Platform.environment.forEach((key, value) {
        // Do not override keys already set as part of environment.
        if (!environment!.containsKey(key)) {
          _environment.add('$key=$value');
        }
      });
    }

    if (_modeHasStdio(_mode)) {
      // stdin going to process.
      _stdin = _StdSink(_Socket._writePipe().._owner = this);
      // stdout coming from process.
      _stdout = _StdStream(_Socket._readPipe().._owner = this);
      // stderr coming from process.
      _stderr = _StdStream(_Socket._readPipe().._owner = this);
    }
    if (_modeIsAttached(_mode)) {
      _exitHandler = _Socket._readPipe();
    }
  }

  _NativeSocket get _stdinNativeSocket =>
      (_stdin!._sink as _Socket)._nativeSocket;
  _NativeSocket get _stdoutNativeSocket =>
      (_stdout!._stream as _Socket)._nativeSocket;
  _NativeSocket get _stderrNativeSocket =>
      (_stderr!._stream as _Socket)._nativeSocket;

  static bool _modeIsAttached(ProcessStartMode mode) {
    return (mode == ProcessStartMode.normal) ||
        (mode == ProcessStartMode.inheritStdio);
  }

  static bool _modeHasStdio(ProcessStartMode mode) {
    return (mode == ProcessStartMode.normal) ||
        (mode == ProcessStartMode.detachedWithStdio);
  }

  static String _getShellCommand() {
    if (Platform.isWindows) {
      return 'cmd.exe';
    }
    return '/bin/sh';
  }

  static List<String> _getShellArguments(
    String executable,
    List<String> arguments,
  ) {
    List<String> shellArguments = [];
    if (Platform.isWindows) {
      shellArguments.add('/c');
      shellArguments.add(executable);
      for (var arg in arguments) {
        shellArguments.add(arg);
      }
    } else {
      var commandLine = StringBuffer();
      executable = executable.replaceAll("'", "'\"'\"'");
      commandLine.write("'$executable'");
      shellArguments.add("-c");
      for (var arg in arguments) {
        arg = arg.replaceAll("'", "'\"'\"'");
        commandLine.write(" '$arg'");
      }
      shellArguments.add(commandLine.toString());
    }
    return shellArguments;
  }

  String _windowsArgumentEscape(String argument) {
    if (argument.isEmpty) {
      return '""';
    }
    var result = argument;
    if (argument.contains('\t') ||
        argument.contains(' ') ||
        argument.contains('"')) {
      // Produce something that the C runtime on Windows will parse
      // back as this string.

      // Replace any number of '\' followed by '"' with
      // twice as many '\' followed by '\"'.
      var backslash = '\\'.codeUnitAt(0);
      var sb = StringBuffer();
      var nextPos = 0;
      var quotePos = argument.indexOf('"', nextPos);
      while (quotePos != -1) {
        var numBackslash = 0;
        var pos = quotePos - 1;
        while (pos >= 0 && argument.codeUnitAt(pos) == backslash) {
          numBackslash++;
          pos--;
        }
        sb.write(argument.substring(nextPos, quotePos - numBackslash));
        for (var i = 0; i < numBackslash; i++) {
          sb.write(r'\\');
        }
        sb.write(r'\"');
        nextPos = quotePos + 1;
        quotePos = argument.indexOf('"', nextPos);
      }
      sb.write(argument.substring(nextPos, argument.length));
      result = sb.toString();

      // Add '"' at the beginning and end and replace all '\' at
      // the end with two '\'.
      sb = StringBuffer('"');
      sb.write(result);
      nextPos = argument.length - 1;
      while (argument.codeUnitAt(nextPos) == backslash) {
        sb.write('\\');
        nextPos--;
      }
      sb.write('"');
      result = sb.toString();
    }

    return result;
  }

  int _intFromBytes(List<int> bytes, int offset) {
    return (bytes[offset] +
        (bytes[offset + 1] << 8) +
        (bytes[offset + 2] << 16) +
        (bytes[offset + 3] << 24));
  }

  Future<Process> _start() {
    var completer = Completer<Process>();
    var stackTrace = StackTrace.current;
    if (_modeIsAttached(_mode)) {
      _exitCode = Completer<int>();
    }
    // TODO(ager): Make the actual process starting really async instead of
    // simulating it with a timer.
    Timer.run(() {
      var status = _ProcessStartStatus();
      bool success = _startNative(
        _Namespace._namespace,
        _path,
        _arguments,
        _workingDirectory,
        _environment,
        _mode._mode,
        _modeHasStdio(_mode) ? _stdinNativeSocket : null,
        _modeHasStdio(_mode) ? _stdoutNativeSocket : null,
        _modeHasStdio(_mode) ? _stderrNativeSocket : null,
        _modeIsAttached(_mode) ? _exitHandler._nativeSocket : null,
        status,
      );
      if (!success) {
        completer.completeError(
          ProcessException(
            _path,
            _arguments,
            status._errorMessage!,
            status._errorCode!,
          ),
          stackTrace,
        );
        return;
      }

      _started = true;
      final resourceInfo = _SpawnedProcessResourceInfo(this);

      // Setup an exit handler to handle internal cleanup and possible
      // callback when a process terminates.
      if (_modeIsAttached(_mode)) {
        int exitDataRead = 0;
        final int EXIT_DATA_SIZE = 8;
        List<int> exitDataBuffer = List<int>.filled(EXIT_DATA_SIZE, 0);
        _exitHandler.listen((data) {
          int exitCode(List<int> ints) {
            var code = _intFromBytes(ints, 0);
            var negative = _intFromBytes(ints, 4);
            assert(negative == 0 || negative == 1);
            return (negative == 0) ? code : -code;
          }

          void handleExit() {
            _ended = true;
            _exitCode!.complete(exitCode(exitDataBuffer));
            // Kill stdin, helping hand if the user forgot to do it.
            if (_modeHasStdio(_mode)) {
              (_stdin!._sink as _Socket).destroy();
            }
            resourceInfo.stopped();
          }

          exitDataBuffer.setRange(
            exitDataRead,
            exitDataRead + data.length,
            data,
          );
          exitDataRead += data.length;
          if (exitDataRead == EXIT_DATA_SIZE) {
            handleExit();
          }
        });
      }

      completer.complete(this);
    });
    return completer.future;
  }

  ProcessResult _runAndWait(
    Encoding? stdoutEncoding,
    Encoding? stderrEncoding,
  ) {
    var status = _ProcessStartStatus();
    _exitCode = Completer<int>();
    bool success = _startNative(
      _Namespace._namespace,
      _path,
      _arguments,
      _workingDirectory,
      _environment,
      ProcessStartMode.normal._mode,
      _stdinNativeSocket,
      _stdoutNativeSocket,
      _stderrNativeSocket,
      _exitHandler._nativeSocket,
      status,
    );
    if (!success) {
      throw ProcessException(
        _path,
        _arguments,
        status._errorMessage!,
        status._errorCode!,
      );
    }

    final resourceInfo = _SpawnedProcessResourceInfo(this);

    var result = _wait(
      _stdinNativeSocket,
      _stdoutNativeSocket,
      _stderrNativeSocket,
      _exitHandler._nativeSocket,
    );

    getOutput(output, encoding) {
      if (encoding == null) return output;
      return encoding.decode(output);
    }

    resourceInfo.stopped();

    return ProcessResult(
      result[0],
      result[1],
      getOutput(result[2], stdoutEncoding),
      getOutput(result[3], stderrEncoding),
    );
  }

  @pragma("vm:external-name", "Process_Start")
  external bool _startNative(
    _Namespace namespace,
    String path,
    List<String> arguments,
    String? workingDirectory,
    List<String> environment,
    int mode,
    _NativeSocket? stdin,
    _NativeSocket? stdout,
    _NativeSocket? stderr,
    _NativeSocket? exitHandler,
    _ProcessStartStatus status,
  );

  @pragma("vm:external-name", "Process_Wait")
  external _wait(
    _NativeSocket? stdin,
    _NativeSocket? stdout,
    _NativeSocket? stderr,
    _NativeSocket exitHandler,
  );

  Stream<List<int>> get stdout =>
      _stdout ?? (throw StateError("stdio is not connected"));

  Stream<List<int>> get stderr =>
      _stderr ?? (throw StateError("stdio is not connected"));

  IOSink get stdin => _stdin ?? (throw StateError("stdio is not connected"));

  Future<int> get exitCode =>
      _exitCode?.future ?? (throw StateError("Process is detached"));

  bool kill([ProcessSignal signal = ProcessSignal.sigterm]) {
    // TODO(40614): Remove once non-nullability is sound.
    ArgumentError.checkNotNull(kill, "kill");
    assert(_started);
    if (_ended) return false;
    return _ProcessUtils._killPid(pid, signal.signalNumber);
  }

  int get pid => _ProcessUtils._pid(this);

  late String _path;
  late List<String> _arguments;
  String? _workingDirectory;
  late List<String> _environment;
  final ProcessStartMode _mode;
  // Private methods of Socket are used by _in, _out, and _err.
  _StdSink? _stdin;
  _StdStream? _stdout;
  _StdStream? _stderr;
  late _Socket _exitHandler;
  bool _ended = false;
  bool _started = false;
  Completer<int>? _exitCode;
}

// _NonInteractiveProcess is a wrapper around an interactive process
// that buffers output so it can be delivered when the process exits.
// _NonInteractiveProcess is used to implement the Process.run
// method.
Future<ProcessResult> _runNonInteractiveProcess(
  String path,
  List<String> arguments,
  String? workingDirectory,
  Map<String, String>? environment,
  bool includeParentEnvironment,
  bool runInShell,
  Encoding? stdoutEncoding,
  Encoding? stderrEncoding,
) {
  // Start the underlying process.
  return Process.start(
    path,
    arguments,
    workingDirectory: workingDirectory,
    environment: environment,
    includeParentEnvironment: includeParentEnvironment,
    runInShell: runInShell,
  ).then((Process p) {
    int pid = p.pid;

    // Make sure the process stdin is closed.
    p.stdin.close();

    // Setup stdout and stderr handling.
    Future foldStream(Stream<List<int>> stream, Encoding? encoding) {
      if (encoding == null) {
        return stream
            .fold<BytesBuilder>(
              BytesBuilder(),
              (builder, data) => builder..add(data),
            )
            .then((builder) => builder.takeBytes());
      } else {
        return stream
            .transform(encoding.decoder)
            .fold<StringBuffer>(StringBuffer(), (buf, data) {
              buf.write(data);
              return buf;
            })
            .then((sb) => sb.toString());
      }
    }

    Future stdout = foldStream(p.stdout, stdoutEncoding);
    Future stderr = foldStream(p.stderr, stderrEncoding);

    return Future.wait([p.exitCode, stdout, stderr]).then((result) {
      return ProcessResult(pid, result[0], result[1], result[2]);
    });
  });
}

ProcessResult _runNonInteractiveProcessSync(
  String executable,
  List<String> arguments,
  String? workingDirectory,
  Map<String, String>? environment,
  bool includeParentEnvironment,
  bool runInShell,
  Encoding? stdoutEncoding,
  Encoding? stderrEncoding,
) {
  var process = _ProcessImpl(
    executable,
    arguments,
    workingDirectory,
    environment,
    includeParentEnvironment,
    runInShell,
    ProcessStartMode.normal,
  );
  return process._runAndWait(stdoutEncoding, stderrEncoding);
}
