// 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)));
        case '-':
          sources.remove(Uri.parse(message.substring(1)));
        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();
}
