// Copyright (c) 2020, 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.

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

/// Contains methods used to communicate DartDev results back to the VM.
///
/// Messages are received in runtime/bin/dartdev_isolate.cc.
abstract class VmInteropHandler {
  /// Initializes [VmInteropHandler] to utilize [port] to communicate with the
  /// VM.
  static void initialize(SendPort? port) => _port = port;

  /// Notifies the VM to run [script] with [args] upon DartDev exit.
  ///
  /// If [packageConfigOverride] is given, that is where the packageConfig is found.
  ///
  /// If [markMainIsolateAsSystemIsolate] is given and set to true, the spawned
  /// isolate will run with `--mark-main-isolate-as-system-isolate` enabled.
  ///
  /// If [useExecProcess] is given and set to true, the script is executed by
  /// execing it (On Linux/Mac the exec call is used, on Windows a new child
  /// process is started).
  static void run(
    String script,
    List<String> args, {
    String? packageConfigOverride,
    // TODO(bkonyi): remove once DartDev moves to AOT and this flag can be
    // provided directly to the process spawned by `dart run` and `dart test`.
    //
    // See https://github.com/dart-lang/sdk/issues/53576
    bool markMainIsolateAsSystemIsolate = false,
    bool useExecProcess = false,

    /// When [useExecProcess] pass this path to signal that it originates from
    /// another file. Used for launching from a dill file while behaving as if
    /// launched directly from a dart file.
    String? scriptUriOverride,
  }) {
    List<String> argsList;
    if (useExecProcess && Platform.isWindows) {
      // On Windows if a new process is used to execute the script we
      // need to escape the script path and all the arguments as we
      // construct a single command line string to be passed to the
      // Windows process create call.
      if (script.contains(' ') && !script.contains('"')) {
        // Escape paths that may contain spaces
        script = '"$script"';
      }
      if (scriptUriOverride != null &&
          scriptUriOverride.contains(' ') &&
          !scriptUriOverride.contains('"')) {
        // Escape paths that may contain spaces
        scriptUriOverride = '"$scriptUriOverride"';
      }
      argsList = [
        for (int i = 0; i < args.length; i++) _windowsArgumentEscape(args[i]),
      ];
    } else {
      // Copy the list so it doesn't get GC'd underneath us.
      argsList = args.toList();
    }
    final port = _port;
    if (port == null) return;
    final message = <dynamic>[
      useExecProcess ? _kResultRunExec : _kResultRun,
      script,
      if (useExecProcess) scriptUriOverride,
      packageConfigOverride,
      markMainIsolateAsSystemIsolate,
      argsList,
    ];
    port.send(message);
  }

  /// Notifies the VM that DartDev has completed running. If provided a
  /// non-zero [exitCode], the VM will terminate with the given exit code.
  static void exit(int? exitCode) {
    final port = _port;
    if (port == null) return;
    final message = <dynamic>[_kResultExit, exitCode];
    port.send(message);
  }

  /// Sets the environment variable [name] to [value] for the current process.
  ///
  /// If [value] is null, the environment variable is removed.
  static Future<void> setEnvironmentVariable(String name, String? value) async {
    final port = _port;
    if (port == null) return;
    final replyPort = RawReceivePort();
    final completer = Completer<void>();
    replyPort.handler = (message) {
      completer.complete();
      replyPort.close();
    };
    final message = <dynamic>[
      _kResultSetEnvironmentVariable,
      replyPort.sendPort,
      name,
      value,
    ];
    port.send(message);
    await completer.future;
  }

  /// This code is identical to the one in process_patch.dart, please ensure
  /// changes made here are also done in process_patch.dart.
  /// TODO : figure out if this functionality can be abstracted out to a
  ///        common place.
  static 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;
  }

  // Note: keep in sync with runtime/bin/dartdev.cc
  static const int _kResultRun = 1;
  static const int _kResultRunExec = 2;
  static const int _kResultExit = 3;
  static const int _kResultSetEnvironmentVariable = 4;

  static SendPort? _port;
}
