// Copyright 2014 The Flutter Authors. 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:typed_data';

import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:process/process.dart';
import 'package:usage/uuid/uuid.dart';

import 'artifacts.dart';
import 'base/common.dart';
import 'base/file_system.dart';
import 'base/io.dart';
import 'base/logger.dart';
import 'base/platform.dart';
import 'build_info.dart';
import 'convert.dart';

/// Opt-in changes to the dart compilers.
const List<String> kDartCompilerExperiments = <String>[
];

/// The target model describes the set of core libraries that are available within
/// the SDK.
class TargetModel {
  /// Parse a [TargetModel] from a raw string.
  ///
  /// Throws an exception if passed a value other than 'flutter',
  /// 'flutter_runner', 'vm', or 'dartdevc'.
  factory TargetModel(String rawValue) {
    switch (rawValue) {
      case 'flutter':
        return flutter;
      case 'flutter_runner':
        return flutterRunner;
      case 'vm':
        return vm;
      case 'dartdevc':
        return dartdevc;
    }
    throw Exception('Unexpected target model $rawValue');
  }

  const TargetModel._(this._value);

  /// The Flutter patched Dart SDK.
  static const TargetModel flutter = TargetModel._('flutter');

  /// The Fuchsia patched SDK.
  static const TargetModel flutterRunner = TargetModel._('flutter_runner');

  /// The Dart VM.
  static const TargetModel vm = TargetModel._('vm');

  /// The development compiler for JavaScript.
  static const TargetModel dartdevc = TargetModel._('dartdevc');

  final String _value;

  @override
  String toString() => _value;
}

class CompilerOutput {
  const CompilerOutput(this.outputFilename, this.errorCount, this.sources, {this.expressionData});

  final String outputFilename;
  final int errorCount;
  final List<Uri> sources;

  /// This field is only non-null for expression compilation requests.
  final Uint8List? expressionData;
}

enum StdoutState { CollectDiagnostic, CollectDependencies }

/// Handles stdin/stdout communication with the frontend server.
class StdoutHandler {
  StdoutHandler({
    required Logger logger,
    required FileSystem fileSystem,
  }) : _logger = logger,
       _fileSystem = fileSystem {
    reset();
  }

  final Logger _logger;
  final FileSystem _fileSystem;

  String? boundaryKey;
  StdoutState state = StdoutState.CollectDiagnostic;
  Completer<CompilerOutput?>? compilerOutput;
  final List<Uri> sources = <Uri>[];

  bool _suppressCompilerMessages = false;
  bool _expectSources = true;
  bool _readFile = false;

  void handler(String message) {
    const String kResultPrefix = 'result ';
    if (boundaryKey == null && message.startsWith(kResultPrefix)) {
      boundaryKey = message.substring(kResultPrefix.length);
      return;
    }
    final String? messageBoundaryKey = boundaryKey;
    if (messageBoundaryKey != null && message.startsWith(messageBoundaryKey)) {
      if (_expectSources) {
        if (state == StdoutState.CollectDiagnostic) {
          state = StdoutState.CollectDependencies;
          return;
        }
      }
      if (message.length <= messageBoundaryKey.length) {
        compilerOutput?.complete(null);
        return;
      }
      final int spaceDelimiter = message.lastIndexOf(' ');
      final String fileName = message.substring(messageBoundaryKey.length + 1, spaceDelimiter);
      final int errorCount = int.parse(message.substring(spaceDelimiter + 1).trim());
      Uint8List? expressionData;
      if (_readFile) {
        expressionData = _fileSystem.file(fileName).readAsBytesSync();
      }
      final CompilerOutput output = CompilerOutput(
        fileName,
        errorCount,
        sources,
        expressionData: expressionData,
      );
      compilerOutput?.complete(output);
      return;
    }
    if (state == StdoutState.CollectDiagnostic) {
      if (!_suppressCompilerMessages) {
        _logger.printError(message);
      } else {
        _logger.printTrace(message);
      }
    } else {
      assert(state == StdoutState.CollectDependencies);
      switch (message[0]) {
        case '+':
          sources.add(Uri.parse(message.substring(1)));
          break;
        case '-':
          sources.remove(Uri.parse(message.substring(1)));
          break;
        default:
          _logger.printTrace('Unexpected prefix for $message uri - ignoring');
      }
    }
  }

  // This is needed to get ready to process next compilation result output,
  // with its own boundary key and new completer.
  void reset({ bool suppressCompilerMessages = false, bool expectSources = true, bool readFile = false }) {
    boundaryKey = null;
    compilerOutput = Completer<CompilerOutput?>();
    _suppressCompilerMessages = suppressCompilerMessages;
    _expectSources = expectSources;
    _readFile = readFile;
    state = StdoutState.CollectDiagnostic;
  }
}

/// List the preconfigured build options for a given build mode.
List<String> buildModeOptions(BuildMode mode, List<String> dartDefines) {
  switch (mode) {
    case BuildMode.debug:
      return <String>[
        // These checks allow the CLI to override the value of this define for unit
        // testing the framework.
        if (!dartDefines.any((String define) => define.startsWith('dart.vm.profile')))
          '-Ddart.vm.profile=false',
        if (!dartDefines.any((String define) => define.startsWith('dart.vm.product')))
          '-Ddart.vm.product=false',
        '--enable-asserts',
      ];
    case BuildMode.profile:
      return <String>[
        // These checks allow the CLI to override the value of this define for
        // benchmarks with most timeline traces disabled.
        if (!dartDefines.any((String define) => define.startsWith('dart.vm.profile')))
          '-Ddart.vm.profile=true',
        if (!dartDefines.any((String define) => define.startsWith('dart.vm.product')))
          '-Ddart.vm.product=false',
        ...kDartCompilerExperiments,
      ];
    case BuildMode.release:
      return <String>[
        '-Ddart.vm.profile=false',
        '-Ddart.vm.product=true',
        ...kDartCompilerExperiments,
      ];
  }
  throw Exception('Unknown BuildMode: $mode');
}

/// A compiler interface for producing single (non-incremental) kernel files.
class KernelCompiler {
  KernelCompiler({
    required FileSystem fileSystem,
    required Logger logger,
    required ProcessManager processManager,
    required Artifacts artifacts,
    required List<String> fileSystemRoots,
    String? fileSystemScheme,
    @visibleForTesting StdoutHandler? stdoutHandler,
  }) : _logger = logger,
       _fileSystem = fileSystem,
       _artifacts = artifacts,
       _processManager = processManager,
       _fileSystemScheme = fileSystemScheme,
       _fileSystemRoots = fileSystemRoots,
       _stdoutHandler = stdoutHandler ?? StdoutHandler(logger: logger, fileSystem: fileSystem);

  final FileSystem _fileSystem;
  final Artifacts _artifacts;
  final ProcessManager _processManager;
  final Logger _logger;
  final String? _fileSystemScheme;
  final List<String> _fileSystemRoots;
  final StdoutHandler _stdoutHandler;

  Future<CompilerOutput?> compile({
    required String sdkRoot,
    String? mainPath,
    String? outputFilePath,
    String? depFilePath,
    TargetModel targetModel = TargetModel.flutter,
    bool linkPlatformKernelIn = false,
    bool aot = false,
    List<String>? extraFrontEndOptions,
    List<String>? fileSystemRoots,
    String? fileSystemScheme,
    String? initializeFromDill,
    String? platformDill,
    Directory? buildDir,
    bool checkDartPluginRegistry = false,
    required String? packagesPath,
    required BuildMode buildMode,
    required bool trackWidgetCreation,
    required List<String> dartDefines,
    required PackageConfig packageConfig,
  }) async {
    final TargetPlatform? platform = targetModel == TargetModel.dartdevc ? TargetPlatform.web_javascript : null;
    final String frontendServer = _artifacts.getArtifactPath(
      Artifact.frontendServerSnapshotForEngineDartSdk,
      platform: platform,
    );
    // This is a URI, not a file path, so the forward slash is correct even on Windows.
    if (!sdkRoot.endsWith('/')) {
      sdkRoot = '$sdkRoot/';
    }
    final String engineDartPath = _artifacts.getArtifactPath(Artifact.engineDartBinary, platform: platform);
    if (!_processManager.canRun(engineDartPath)) {
      throwToolExit('Unable to find Dart binary at $engineDartPath');
    }
    String? mainUri;
    final File mainFile = _fileSystem.file(mainPath);
    final Uri mainFileUri = mainFile.uri;
    if (packagesPath != null) {
      mainUri = packageConfig.toPackageUri(mainFileUri)?.toString();
    }
    mainUri ??= toMultiRootPath(mainFileUri, _fileSystemScheme, _fileSystemRoots, _fileSystem.path.separator == r'\');
    if (outputFilePath != null && !_fileSystem.isFileSync(outputFilePath)) {
      _fileSystem.file(outputFilePath).createSync(recursive: true);
    }

    // Check if there's a Dart plugin registrant.
    // This is contained in the file `dart_plugin_registrant.dart` under `.dart_tools/flutter_build/`.
    final File? dartPluginRegistrant = checkDartPluginRegistry
        ? buildDir?.parent.childFile('dart_plugin_registrant.dart')
        : null;

    String? dartPluginRegistrantUri;
    if (dartPluginRegistrant != null && dartPluginRegistrant.existsSync()) {
      final Uri dartPluginRegistrantFileUri = dartPluginRegistrant.uri;
      dartPluginRegistrantUri = packageConfig.toPackageUri(dartPluginRegistrantFileUri)?.toString() ??
        toMultiRootPath(dartPluginRegistrantFileUri, _fileSystemScheme, _fileSystemRoots, _fileSystem.path.separator == r'\');
    }

    final List<String> command = <String>[
      engineDartPath,
      '--disable-dart-dev',
      frontendServer,
      '--sdk-root',
      sdkRoot,
      '--target=$targetModel',
      '--no-print-incremental-dependencies',
      for (final Object dartDefine in dartDefines)
        '-D$dartDefine',
      ...buildModeOptions(buildMode, dartDefines),
      if (trackWidgetCreation) '--track-widget-creation',
      if (!linkPlatformKernelIn) '--no-link-platform',
      if (aot) ...<String>[
        '--aot',
        '--tfa',
      ],
      if (packagesPath != null) ...<String>[
        '--packages',
        packagesPath,
      ],
      if (outputFilePath != null) ...<String>[
        '--output-dill',
        outputFilePath,
      ],
      if (depFilePath != null && (fileSystemRoots == null || fileSystemRoots.isEmpty)) ...<String>[
        '--depfile',
        depFilePath,
      ],
      if (fileSystemRoots != null)
        for (final String root in fileSystemRoots) ...<String>[
          '--filesystem-root',
          root,
        ],
      if (fileSystemScheme != null) ...<String>[
        '--filesystem-scheme',
        fileSystemScheme,
      ],
      if (initializeFromDill != null) ...<String>[
        '--incremental',
        '--initialize-from-dill',
        initializeFromDill,
      ],
      if (platformDill != null) ...<String>[
        '--platform',
        platformDill,
      ],
      if (dartPluginRegistrantUri != null) ...<String>[
        '--source',
        dartPluginRegistrantUri,
        '--source',
        'package:flutter/src/dart_plugin_registrant.dart',
        '-Dflutter.dart_plugin_registrant=$dartPluginRegistrantUri',
      ],
      // See: https://github.com/flutter/flutter/issues/103994
      '--verbosity=error',
      ...?extraFrontEndOptions,
      mainUri,
    ];

    _logger.printTrace(command.join(' '));
    final Process server = await _processManager.start(command);

    server.stderr
      .transform<String>(utf8.decoder)
      .listen(_logger.printError);
    server.stdout
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen(_stdoutHandler.handler);
    final int exitCode = await server.exitCode;
    if (exitCode == 0) {
      return _stdoutHandler.compilerOutput?.future;
    }
    return null;
  }
}

/// Class that allows to serialize compilation requests to the compiler.
abstract class _CompilationRequest {
  _CompilationRequest(this.completer);

  Completer<CompilerOutput?> completer;

  Future<CompilerOutput?> _run(DefaultResidentCompiler compiler);

  Future<void> run(DefaultResidentCompiler compiler) async {
    completer.complete(await _run(compiler));
  }
}

class _RecompileRequest extends _CompilationRequest {
  _RecompileRequest(
    super.completer,
    this.mainUri,
    this.invalidatedFiles,
    this.outputPath,
    this.packageConfig,
    this.suppressErrors,
    {this.additionalSourceUri}
  );

  Uri mainUri;
  List<Uri>? invalidatedFiles;
  String outputPath;
  PackageConfig packageConfig;
  bool suppressErrors;
  final Uri? additionalSourceUri;

  @override
  Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
      compiler._recompile(this);
}

class _CompileExpressionRequest extends _CompilationRequest {
  _CompileExpressionRequest(
    super.completer,
    this.expression,
    this.definitions,
    this.typeDefinitions,
    this.libraryUri,
    this.klass,
    this.isStatic,
  );

  String expression;
  List<String>? definitions;
  List<String>? typeDefinitions;
  String? libraryUri;
  String? klass;
  bool isStatic;

  @override
  Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
      compiler._compileExpression(this);
}

class _CompileExpressionToJsRequest extends _CompilationRequest {
  _CompileExpressionToJsRequest(
    super.completer,
    this.libraryUri,
    this.line,
    this.column,
    this.jsModules,
    this.jsFrameValues,
    this.moduleName,
    this.expression,
  );

  final String? libraryUri;
  final int line;
  final int column;
  final Map<String, String>? jsModules;
  final Map<String, String>? jsFrameValues;
  final String? moduleName;
  final String? expression;

  @override
  Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
      compiler._compileExpressionToJs(this);
}

class _RejectRequest extends _CompilationRequest {
  _RejectRequest(super.completer);

  @override
  Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
      compiler._reject();
}

/// Wrapper around incremental frontend server compiler, that communicates with
/// server via stdin/stdout.
///
/// The wrapper is intended to stay resident in memory as user changes, reloads,
/// restarts the Flutter app.
abstract class ResidentCompiler {
  factory ResidentCompiler(String sdkRoot, {
    required BuildMode buildMode,
    required Logger logger,
    required ProcessManager processManager,
    required Artifacts artifacts,
    required Platform platform,
    required FileSystem fileSystem,
    bool testCompilation,
    bool trackWidgetCreation,
    String packagesPath,
    List<String> fileSystemRoots,
    String? fileSystemScheme,
    String initializeFromDill,
    bool assumeInitializeFromDillUpToDate,
    TargetModel targetModel,
    bool unsafePackageSerialization,
    List<String> extraFrontEndOptions,
    String platformDill,
    List<String>? dartDefines,
    String librariesSpec,
  }) = DefaultResidentCompiler;

  // TODO(zanderso): find a better way to configure additional file system
  // roots from the runner.
  // See: https://github.com/flutter/flutter/issues/50494
  void addFileSystemRoot(String root);

  /// If invoked for the first time, it compiles Dart script identified by
  /// [mainPath], [invalidatedFiles] list is ignored.
  /// On successive runs [invalidatedFiles] indicates which files need to be
  /// recompiled. If [mainPath] is [null], previously used [mainPath] entry
  /// point that is used for recompilation.
  /// Binary file name is returned if compilation was successful, otherwise
  /// null is returned.
  ///
  /// If [checkDartPluginRegistry] is true, it is the caller's responsibility
  /// to ensure that the generated registrant file has been updated such that
  /// it is wrapping [mainUri].
  Future<CompilerOutput?> recompile(
    Uri mainUri,
    List<Uri>? invalidatedFiles, {
    required String outputPath,
    required PackageConfig packageConfig,
    required FileSystem fs,
    String? projectRootPath,
    bool suppressErrors = false,
    bool checkDartPluginRegistry = false,
    File? dartPluginRegistrant,
  });

  Future<CompilerOutput?> compileExpression(
    String expression,
    List<String>? definitions,
    List<String>? typeDefinitions,
    String? libraryUri,
    String? klass,
    bool isStatic,
  );

  /// Compiles [expression] in [libraryUri] at [line]:[column] to JavaScript
  /// in [moduleName].
  ///
  /// Values listed in [jsFrameValues] are substituted for their names in the
  /// [expression].
  ///
  /// Ensures that all [jsModules] are loaded and accessible inside the
  /// expression.
  ///
  /// Example values of parameters:
  /// [moduleName] is of the form '/packages/hello_world_main.dart'
  /// [jsFrameValues] is a map from js variable name to its primitive value
  /// or another variable name, for example
  /// { 'x': '1', 'y': 'y', 'o': 'null' }
  /// [jsModules] is a map from variable name to the module name, where
  /// variable name is the name originally used in JavaScript to contain the
  /// module object, for example:
  /// { 'dart':'dart_sdk', 'main': '/packages/hello_world_main.dart' }
  /// Returns a [CompilerOutput] including the name of the file containing the
  /// compilation result and a number of errors.
  Future<CompilerOutput?> compileExpressionToJs(
    String libraryUri,
    int line,
    int column,
    Map<String, String> jsModules,
    Map<String, String> jsFrameValues,
    String moduleName,
    String expression,
  );

  /// Should be invoked when results of compilation are accepted by the client.
  ///
  /// Either [accept] or [reject] should be called after every [recompile] call.
  void accept();

  /// Should be invoked when results of compilation are rejected by the client.
  ///
  /// Either [accept] or [reject] should be called after every [recompile] call.
  Future<CompilerOutput?> reject();

  /// Should be invoked when frontend server compiler should forget what was
  /// accepted previously so that next call to [recompile] produces complete
  /// kernel file.
  void reset();

  Future<Object> shutdown();
}

@visibleForTesting
class DefaultResidentCompiler implements ResidentCompiler {
  DefaultResidentCompiler(
    String sdkRoot, {
    required this.buildMode,
    required Logger logger,
    required ProcessManager processManager,
    required Artifacts artifacts,
    required Platform platform,
    required FileSystem fileSystem,
    this.testCompilation = false,
    this.trackWidgetCreation = true,
    this.packagesPath,
    List<String> fileSystemRoots = const <String>[],
    this.fileSystemScheme,
    this.initializeFromDill,
    this.assumeInitializeFromDillUpToDate = false,
    this.targetModel = TargetModel.flutter,
    this.unsafePackageSerialization = false,
    this.extraFrontEndOptions,
    this.platformDill,
    List<String>? dartDefines,
    this.librariesSpec,
    @visibleForTesting StdoutHandler? stdoutHandler,
  }) : _logger = logger,
       _processManager = processManager,
       _artifacts = artifacts,
       _stdoutHandler = stdoutHandler ?? StdoutHandler(logger: logger, fileSystem: fileSystem),
       _platform = platform,
       dartDefines = dartDefines ?? const <String>[],
       // This is a URI, not a file path, so the forward slash is correct even on Windows.
       sdkRoot = sdkRoot.endsWith('/') ? sdkRoot : '$sdkRoot/',
       // Make a copy, we might need to modify it later.
       fileSystemRoots = List<String>.from(fileSystemRoots);

  final Logger _logger;
  final ProcessManager _processManager;
  final Artifacts _artifacts;
  final Platform _platform;

  final bool testCompilation;
  final BuildMode buildMode;
  final bool trackWidgetCreation;
  final String? packagesPath;
  final TargetModel targetModel;
  final List<String> fileSystemRoots;
  final String? fileSystemScheme;
  final String? initializeFromDill;
  final bool assumeInitializeFromDillUpToDate;
  final bool unsafePackageSerialization;
  final List<String>? extraFrontEndOptions;
  final List<String> dartDefines;
  final String? librariesSpec;

  @override
  void addFileSystemRoot(String root) {
    fileSystemRoots.add(root);
  }

  /// The path to the root of the Dart SDK used to compile.
  ///
  /// This is used to resolve the [platformDill].
  final String sdkRoot;

  /// The path to the platform dill file.
  ///
  /// This does not need to be provided for the normal Flutter workflow.
  final String? platformDill;

  Process? _server;
  final StdoutHandler _stdoutHandler;
  bool _compileRequestNeedsConfirmation = false;

  final StreamController<_CompilationRequest> _controller = StreamController<_CompilationRequest>();

  @override
  Future<CompilerOutput?> recompile(
    Uri mainUri,
    List<Uri>? invalidatedFiles, {
    required String outputPath,
    required PackageConfig packageConfig,
    bool suppressErrors = false,
    bool checkDartPluginRegistry = false,
    File? dartPluginRegistrant,
    String? projectRootPath,
    FileSystem? fs,
  }) async {
    if (!_controller.hasListener) {
      _controller.stream.listen(_handleCompilationRequest);
    }
    Uri? additionalSourceUri;
    // `dart_plugin_registrant.dart` contains the Dart plugin registry.
    if (checkDartPluginRegistry && dartPluginRegistrant != null && dartPluginRegistrant.existsSync()) {
      additionalSourceUri = dartPluginRegistrant.uri;
    }
    final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
    _controller.add(_RecompileRequest(
      completer,
      mainUri,
      invalidatedFiles,
      outputPath,
      packageConfig,
      suppressErrors,
      additionalSourceUri: additionalSourceUri,
    ));
    return completer.future;
  }

  Future<CompilerOutput?> _recompile(_RecompileRequest request) async {
    _stdoutHandler.reset();
    _compileRequestNeedsConfirmation = true;
    _stdoutHandler._suppressCompilerMessages = request.suppressErrors;

    final String mainUri = request.packageConfig.toPackageUri(request.mainUri)?.toString() ??
      toMultiRootPath(request.mainUri, fileSystemScheme, fileSystemRoots, _platform.isWindows);

    String? additionalSourceUri;
    if (request.additionalSourceUri != null) {
      additionalSourceUri = request.packageConfig.toPackageUri(request.additionalSourceUri!)?.toString() ??
        toMultiRootPath(request.additionalSourceUri!, fileSystemScheme, fileSystemRoots, _platform.isWindows);
    }

    final Process? server = _server;
    if (server == null) {
      return _compile(mainUri, request.outputPath, additionalSourceUri: additionalSourceUri);
    }
    final String inputKey = Uuid().generateV4();

    server.stdin.writeln('recompile $mainUri $inputKey');
    _logger.printTrace('<- recompile $mainUri $inputKey');
    final List<Uri>? invalidatedFiles = request.invalidatedFiles;
    if (invalidatedFiles != null) {
      for (final Uri fileUri in invalidatedFiles) {
        String message;
        if (fileUri.scheme == 'package') {
          message = fileUri.toString();
        } else {
          message = request.packageConfig.toPackageUri(fileUri)?.toString() ??
              toMultiRootPath(fileUri, fileSystemScheme, fileSystemRoots, _platform.isWindows);
        }
        server.stdin.writeln(message);
        _logger.printTrace(message);
      }
    }
    server.stdin.writeln(inputKey);
    _logger.printTrace('<- $inputKey');

    return _stdoutHandler.compilerOutput?.future;
  }

  final List<_CompilationRequest> _compilationQueue = <_CompilationRequest>[];

  Future<void> _handleCompilationRequest(_CompilationRequest request) async {
    final bool isEmpty = _compilationQueue.isEmpty;
    _compilationQueue.add(request);
    // Only trigger processing if queue was empty - i.e. no other requests
    // are currently being processed. This effectively enforces "one
    // compilation request at a time".
    if (isEmpty) {
      while (_compilationQueue.isNotEmpty) {
        final _CompilationRequest request = _compilationQueue.first;
        await request.run(this);
        _compilationQueue.removeAt(0);
      }
    }
  }

  Future<CompilerOutput?> _compile(
    String scriptUri,
    String? outputPath,
    {String? additionalSourceUri}
  ) async {
    final TargetPlatform? platform = (targetModel == TargetModel.dartdevc) ? TargetPlatform.web_javascript : null;
    final String frontendServer = _artifacts.getArtifactPath(
      Artifact.frontendServerSnapshotForEngineDartSdk,
      platform: platform,
    );
    final List<String> command = <String>[
      _artifacts.getArtifactPath(Artifact.engineDartBinary, platform: platform),
      '--disable-dart-dev',
      frontendServer,
      '--sdk-root',
      sdkRoot,
      '--incremental',
      if (testCompilation)
        '--no-print-incremental-dependencies',
      '--target=$targetModel',
      // TODO(annagrin): remove once this becomes the default behavior
      // in the frontend_server.
      // https://github.com/flutter/flutter/issues/59902
      '--experimental-emit-debug-metadata',
      for (final Object dartDefine in dartDefines)
        '-D$dartDefine',
      if (outputPath != null) ...<String>[
        '--output-dill',
        outputPath,
      ],
      // If we have a platform dill, we don't need to pass the libraries spec,
      // since the information is embedded in the .dill file.
      if (librariesSpec != null && platformDill == null) ...<String>[
        '--libraries-spec',
        librariesSpec!,
      ],
      if (packagesPath != null) ...<String>[
        '--packages',
        packagesPath!,
      ],
      ...buildModeOptions(buildMode, dartDefines),
      if (trackWidgetCreation) '--track-widget-creation',
      for (final String root in fileSystemRoots) ...<String>[
        '--filesystem-root',
        root,
      ],
      if (fileSystemScheme != null) ...<String>[
        '--filesystem-scheme',
        fileSystemScheme!,
      ],
      if (initializeFromDill != null) ...<String>[
        '--initialize-from-dill',
        initializeFromDill!,
      ],
      if (assumeInitializeFromDillUpToDate) '--assume-initialize-from-dill-up-to-date',
      if (additionalSourceUri != null) ...<String>[
        '--source',
        additionalSourceUri,
        '--source',
        'package:flutter/src/dart_plugin_registrant.dart',
        '-Dflutter.dart_plugin_registrant=$additionalSourceUri',
      ],
      if (platformDill != null) ...<String>[
        '--platform',
        platformDill!,
      ],
      if (unsafePackageSerialization == true) '--unsafe-package-serialization',
      // See: https://github.com/flutter/flutter/issues/103994
      '--verbosity=error',
      ...?extraFrontEndOptions,
    ];
    _logger.printTrace(command.join(' '));
    _server = await _processManager.start(command);
    _server?.stdout
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen(
        _stdoutHandler.handler,
        onDone: () {
          // when outputFilename future is not completed, but stdout is closed
          // process has died unexpectedly.
          if (_stdoutHandler.compilerOutput?.isCompleted == false) {
            _stdoutHandler.compilerOutput?.complete(null);
            throwToolExit('the Dart compiler exited unexpectedly.');
          }
        });

    _server?.stderr
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen(_logger.printError);

    unawaited(_server?.exitCode.then((int code) {
      if (code != 0) {
        throwToolExit('the Dart compiler exited unexpectedly.');
      }
    }));

    _server?.stdin.writeln('compile $scriptUri');
    _logger.printTrace('<- compile $scriptUri');

    return _stdoutHandler.compilerOutput?.future;
  }

  @override
  Future<CompilerOutput?> compileExpression(
    String expression,
    List<String>? definitions,
    List<String>? typeDefinitions,
    String? libraryUri,
    String? klass,
    bool isStatic,
  ) async {
    if (!_controller.hasListener) {
      _controller.stream.listen(_handleCompilationRequest);
    }

    final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
    final _CompileExpressionRequest request =  _CompileExpressionRequest(
        completer, expression, definitions, typeDefinitions, libraryUri, klass, isStatic);
    _controller.add(request);
    return completer.future;
  }

  Future<CompilerOutput?> _compileExpression(_CompileExpressionRequest request) async {
    _stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false, readFile: true);

    // 'compile-expression' should be invoked after compiler has been started,
    // program was compiled.
    final Process? server = _server;
    if (server == null) {
      return null;
    }

    final String inputKey = Uuid().generateV4();
    server.stdin
      ..writeln('compile-expression $inputKey')
      ..writeln(request.expression);
    request.definitions?.forEach(server.stdin.writeln);
    server.stdin.writeln(inputKey);
    request.typeDefinitions?.forEach(server.stdin.writeln);
    server.stdin
      ..writeln(inputKey)
      ..writeln(request.libraryUri ?? '')
      ..writeln(request.klass ?? '')
      ..writeln(request.isStatic);

    return _stdoutHandler.compilerOutput?.future;
  }

  @override
  Future<CompilerOutput?> compileExpressionToJs(
    String libraryUri,
    int line,
    int column,
    Map<String, String> jsModules,
    Map<String, String> jsFrameValues,
    String moduleName,
    String expression,
  ) {
    if (!_controller.hasListener) {
      _controller.stream.listen(_handleCompilationRequest);
    }

    final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
    _controller.add(
        _CompileExpressionToJsRequest(
            completer, libraryUri, line, column, jsModules, jsFrameValues, moduleName, expression)
    );
    return completer.future;
  }

  Future<CompilerOutput?> _compileExpressionToJs(_CompileExpressionToJsRequest request) async {
    _stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false);

    // 'compile-expression-to-js' should be invoked after compiler has been started,
    // program was compiled.
    final Process? server = _server;
    if (server == null) {
      return null;
    }

    final String inputKey = Uuid().generateV4();
    server.stdin
      ..writeln('compile-expression-to-js $inputKey')
      ..writeln(request.libraryUri ?? '')
      ..writeln(request.line)
      ..writeln(request.column);
    request.jsModules?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); });
    server.stdin.writeln(inputKey);
    request.jsFrameValues?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); });
    server.stdin
      ..writeln(inputKey)
      ..writeln(request.moduleName ?? '')
      ..writeln(request.expression ?? '');

    return _stdoutHandler.compilerOutput?.future;
  }

  @override
  void accept() {
    if (_compileRequestNeedsConfirmation) {
      _server?.stdin.writeln('accept');
      _logger.printTrace('<- accept');
    }
    _compileRequestNeedsConfirmation = false;
  }

  @override
  Future<CompilerOutput?> reject() {
    if (!_controller.hasListener) {
      _controller.stream.listen(_handleCompilationRequest);
    }

    final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
    _controller.add(_RejectRequest(completer));
    return completer.future;
  }

  Future<CompilerOutput?> _reject() async {
    if (!_compileRequestNeedsConfirmation) {
      return Future<CompilerOutput?>.value();
    }
    _stdoutHandler.reset(expectSources: false);
    _server?.stdin.writeln('reject');
    _logger.printTrace('<- reject');
    _compileRequestNeedsConfirmation = false;
    return _stdoutHandler.compilerOutput?.future;
  }

  @override
  void reset() {
    _server?.stdin.writeln('reset');
    _logger.printTrace('<- reset');
  }

  @override
  Future<Object> shutdown() async {
    // Server was never successfully created.
    final Process? server = _server;
    if (server == null) {
      return 0;
    }
    _logger.printTrace('killing pid ${server.pid}');
    server.kill();
    return server.exitCode;
  }
}

/// Convert a file URI into a multi-root scheme URI if provided, otherwise
/// return unmodified.
@visibleForTesting
String toMultiRootPath(Uri fileUri, String? scheme, List<String> fileSystemRoots, bool windows) {
  if (scheme == null || fileSystemRoots.isEmpty || fileUri.scheme != 'file') {
    return fileUri.toString();
  }
  final String filePath = fileUri.toFilePath(windows: windows);
  for (final String fileSystemRoot in fileSystemRoots) {
    if (filePath.startsWith(fileSystemRoot)) {
      return '$scheme://${filePath.substring(fileSystemRoot.length)}';
    }
  }
  return fileUri.toString();
}
