// 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/config.dart';
import 'base/context.dart';
import 'base/file_system.dart';
import 'base/io.dart';
import 'base/logger.dart';
import 'base/platform.dart';
import 'base/process.dart';
import 'base/utils.dart';
import 'build_info.dart';
import 'bundle.dart';
import 'convert.dart';

/// Opt-in changes to the dart compilers.
const 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) {
    return switch (rawValue) {
      'flutter' => flutter,
      'flutter_runner' => flutterRunner,
      'vm' => vm,
      'dartdevc' => dartdevc,
      _ => throw Exception('Unexpected target model $rawValue'),
    };
  }

  const TargetModel._(this._value);

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

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

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

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

  final String _value;

  @override
  String toString() => _value;
}

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

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

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

  /// This field is only non-null when a compilation error was encountered.
  final String? errorMessage;
}

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 sources = <Uri>[];

  var _suppressCompilerMessages = false;
  var _expectSources = true;
  var _readFile = false;
  var _errorBuffer = StringBuffer();

  void handler(String message) {
    const 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();
        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 output = CompilerOutput(
        fileName,
        errorCount,
        sources,
        expressionData: expressionData,
        errorMessage: _errorBuffer.isNotEmpty ? _errorBuffer.toString() : null,
      );
      compilerOutput?.complete(output);
      return;
    }
    switch (state) {
      case StdoutState.CollectDiagnostic when _suppressCompilerMessages:
        _logger.printTrace(message);
        _errorBuffer.writeln(message);
      case StdoutState.CollectDiagnostic:
        _logger.printError(message);
        _errorBuffer.writeln(message);
      case 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;
    _errorBuffer = StringBuffer();
  }
}

/// List the preconfigured build options for a given build mode.
List<String> buildModeOptions(BuildMode mode, List<String> dartDefines) => switch (mode) {
  BuildMode.debug => <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',
  ],
  BuildMode.profile => <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',
    '--delete-tostring-package-uri=dart:ui',
    '--delete-tostring-package-uri=package:flutter',
    ...kDartCompilerExperiments,
  ],
  BuildMode.release => <String>[
    '-Ddart.vm.profile=false',
    '-Ddart.vm.product=true',
    '--delete-tostring-package-uri=dart:ui',
    '--delete-tostring-package-uri=package:flutter',
    ...kDartCompilerExperiments,
  ],
  _ => throw Exception('Unknown BuildMode: $mode'),
};

final _extraFrontEndOptionsFilterSet = <String>{
  // Don't allow for users to pass --include-unsupported-platform-library-stubs to bypass
  // unsupported library compile time errors as this flag is only safe for use by developer
  // tooling.
  '--include-unsupported-platform-library-stubs',
};

Iterable<String>? _filterExtraFrontEndOptions(List<String>? options) =>
    options?.where((e) => !_extraFrontEndOptionsFilterSet.contains(e));

/// 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,
    String? frontendServerStarterPath,
    List<String>? extraFrontEndOptions,
    List<String>? fileSystemRoots,
    String? fileSystemScheme,
    String? initializeFromDill,
    String? platformDill,
    Directory? buildDir,
    String? targetOS,
    bool checkDartPluginRegistry = false,
    required String? packagesPath,
    required BuildMode buildMode,
    required bool trackWidgetCreation,
    required List<String> dartDefines,
    required PackageConfig packageConfig,
    String? nativeAssets,
  }) async {
    final TargetPlatform? platform = targetModel == TargetModel.dartdevc
        ? TargetPlatform.web_javascript
        : null;
    // This is a URI, not a file path, so the forward slash is correct even on Windows.
    if (!sdkRoot.endsWith('/')) {
      sdkRoot = '$sdkRoot/';
    }
    String? mainUri;
    if (mainPath != null) {
      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> commandToStartFrontendServer;
    if (frontendServerStarterPath != null && frontendServerStarterPath.isNotEmpty) {
      final String engineDartPath = _artifacts.getArtifactPath(
        Artifact.engineDartBinary,
        platform: platform,
      );
      if (!_processManager.canRun(engineDartPath)) {
        throwToolExit('Unable to find Dart binary at $engineDartPath');
      }
      commandToStartFrontendServer = <String>[engineDartPath, frontendServerStarterPath];
    } else {
      final String engineDartAotRuntimePath = _artifacts.getArtifactPath(
        Artifact.engineDartAotRuntime,
        platform: platform,
      );
      if (!_processManager.canRun(engineDartAotRuntimePath)) {
        throwToolExit('Unable to find dartaotruntime binary at $engineDartAotRuntimePath');
      }
      commandToStartFrontendServer = <String>[
        engineDartAotRuntimePath,
        _artifacts.getArtifactPath(
          Artifact.frontendServerSnapshotForEngineDartSdk,
          platform: platform,
        ),
      ];
    }

    final List<String> command =
        commandToStartFrontendServer +
        <String>[
          '--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',
            // The --target-os flag only makes sense for whole program compilation.
            if (targetOS != null) ...<String>['--target-os', targetOS],
          ],
          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',
          ],
          if (nativeAssets != null) ...<String>['--native-assets', nativeAssets],
          // See: https://github.com/flutter/flutter/issues/103994
          '--verbosity=error',
          ...?_filterExtraFrontEndOptions(extraFrontEndOptions),
          mainUri ?? '--native-assets-only',
        ];

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

    server.stderr.transform<String>(utf8.decoder).listen(_logger.printError);
    server.stdout.transform(utf8LineDecoder).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,
    this.nativeAssetsYamlUri,
    required this.recompileRestart,
  });

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

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

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

  String expression;
  List<String>? definitions;
  List<String>? definitionTypes;
  List<String>? typeDefinitions;
  List<String>? typeBounds;
  List<String>? typeDefaults;
  String? libraryUri;
  String? klass;
  String? method;
  bool isStatic;

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

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

  final String? libraryUri;
  final String? scriptUri;
  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();
}

ResidentCompilerFactory get residentCompilerFactory =>
    context.get<ResidentCompilerFactory>() ?? const ResidentCompilerFactory();

/// A factory for generating [ResidentCompiler] instances.
class ResidentCompilerFactory {
  const ResidentCompilerFactory();

  ResidentCompiler create({
    required TargetPlatform targetPlatform,
    required BuildInfo buildInfo,
    required Logger logger,
    required ProcessManager processManager,
    required Artifacts artifacts,
    required Platform platform,
    required FileSystem fileSystem,
    required ShutdownHooks shutdownHooks,
    required Config config,
    bool testCompilation = false,
    TargetModel? targetModelOverride,
  }) {
    String sdkRoot = artifacts.getArtifactPath(
      Artifact.flutterPatchedSdkPath,
      platform: targetPlatform,
      mode: buildInfo.mode,
    );
    String? platformDillPath;
    String? librariesSpec;
    TargetModel targetModel = targetModelOverride ?? .flutter;

    // Configure the compiler to target the DDC runtime.
    if (targetPlatform case .web_javascript) {
      sdkRoot = artifacts.getHostArtifact(HostArtifact.flutterWebSdk).path;
      targetModel = .dartdevc;

      const platformDillName = 'ddc_outline.dill';
      platformDillPath = fileSystem
          .file(
            fileSystem.path.join(
              artifacts.getHostArtifact(.webPlatformKernelFolder).path,
              platformDillName,
            ),
          )
          .absolute
          .uri
          .toString();

      librariesSpec = fileSystem
          .file(artifacts.getHostArtifact(.flutterWebLibrariesJson))
          .uri
          .toString();

      buildInfo = buildInfo.copyWith(
        // Override the filesystem scheme so that the frontend_server can find
        // the generated entrypoint code.
        fileSystemScheme: 'org-dartlang-app',
        extraFrontEndOptions: [
          ...buildInfo.extraFrontEndOptions,
          if (buildInfo.webEnableHotReload)
          // These flags are only valid to be passed when compiling with DDC.
          ...<String>['--dartdevc-canary', '--dartdevc-module-format=ddc'],
        ],
      );
    } else {
      if (targetPlatform case .fuchsia_arm64 || .fuchsia_x64) {
        targetModel = .flutterRunner;
      }
      buildInfo = buildInfo.copyWith(
        extraFrontEndOptions: [
          ...buildInfo.extraFrontEndOptions,
          '--enable-experiment=alternative-invalidation-strategy',
        ],
      );
    }

    return DefaultResidentCompiler(
      sdkRoot,
      buildInfo: buildInfo,
      logger: logger,
      processManager: processManager,
      artifacts: artifacts,
      platform: platform,
      fileSystem: fileSystem,
      shutdownHooks: shutdownHooks,
      config: config,
      targetModel: targetModel,
      platformDill: platformDillPath,
      librariesSpec: librariesSpec,
      testCompilation: testCompilation,
    );
  }
}

/// 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 interface class ResidentCompiler {
  // 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 the Dart script identified by
  /// [mainUri], [invalidatedFiles] list is ignored.
  /// On successive runs [invalidatedFiles] indicates which files need to be
  /// recompiled.
  ///
  /// 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].
  ///
  /// If [recompileRestart] is true, uses the `recompile-restart` instruction
  /// intended for a hot restart instead.
  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,
    Uri? nativeAssetsYaml,
    bool recompileRestart = false,
  });

  Future<CompilerOutput?> compileExpression(
    String expression,
    List<String>? definitions,
    List<String>? definitionTypes,
    List<String>? typeDefinitions,
    List<String>? typeBounds,
    List<String>? typeDefaults,
    String? libraryUri,
    String? klass,
    String? method,
    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,
    String scriptUri,
    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 BuildInfo buildInfo,
    required Logger logger,
    required ProcessManager processManager,
    required this.artifacts,
    required Platform platform,
    required FileSystem fileSystem,
    required ShutdownHooks shutdownHooks,
    required Config config,
    this.testCompilation = false,
    this.targetModel = TargetModel.flutter,
    this.platformDill,
    this.librariesSpec,
    @visibleForTesting StdoutHandler? stdoutHandler,
  }) : buildMode = buildInfo.mode,
       trackWidgetCreation = buildInfo.trackWidgetCreation,
       includeUnsupportedPlatformLibraryStubs = buildInfo.includeUnsupportedPlatformLibraryStubs,
       packagesPath = buildInfo.packageConfigPath,
       initializeFromDill =
           buildInfo.initializeFromDill ??
           getDefaultCachedKernelPath(
             config: config,
             fileSystem: fileSystem,
             trackWidgetCreation: buildInfo.trackWidgetCreation,
             dartDefines: buildInfo.dartDefines,
             extraFrontEndOptions: buildInfo.extraFrontEndOptions,
           ),
       extraFrontEndOptions = buildInfo.extraFrontEndOptions,
       fileSystemScheme = buildInfo.fileSystemScheme,
       assumeInitializeFromDillUpToDate = buildInfo.assumeInitializeFromDillUpToDate,
       frontendServerStarterPath = buildInfo.frontendServerStarterPath,
       _logger = logger,
       _processManager = processManager,
       _shutdownHooks = shutdownHooks,
       _stdoutHandler = stdoutHandler ?? StdoutHandler(logger: logger, fileSystem: fileSystem),
       _platform = platform,
       dartDefines = buildInfo.dartDefines,
       // 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(buildInfo.fileSystemRoots) {
    // Currently, the only developer tooling that requires support for importing unsupported
    // platform libraries at compile time is the widget previewer. Only developer tooling use cases
    // should support this, so this is restricted to the widget previewer's runtime target for now.
    if (includeUnsupportedPlatformLibraryStubs && targetModel != TargetModel.dartdevc) {
      throw StateError(
        'includeUnsupportedPlatformLibraryStubs should only be used by the widget-preview '
        'command.',
      );
    }
  }

  final Logger _logger;
  final ProcessManager _processManager;
  final Artifacts artifacts;
  final Platform _platform;
  final ShutdownHooks _shutdownHooks;

  final bool testCompilation;
  final BuildMode buildMode;
  final bool trackWidgetCreation;
  final bool includeUnsupportedPlatformLibraryStubs;
  final String? packagesPath;
  final TargetModel targetModel;
  final List<String> fileSystemRoots;
  final String? fileSystemScheme;
  final String? initializeFromDill;
  final bool assumeInitializeFromDillUpToDate;
  final String? frontendServerStarterPath;
  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;
  var _compileRequestNeedsConfirmation = false;

  final _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,
    Uri? nativeAssetsYaml,
    bool recompileRestart = false,
  }) 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 = Completer<CompilerOutput?>();
    _controller.add(
      _RecompileRequest(
        completer,
        mainUri,
        invalidatedFiles,
        outputPath,
        packageConfig,
        suppressErrors,
        additionalSourceUri: additionalSourceUri,
        nativeAssetsYamlUri: nativeAssetsYaml,
        recompileRestart: recompileRestart,
      ),
    );
    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 nativeAssets = request.nativeAssetsYamlUri?.toString();
    final Process? server = _server;
    if (server == null) {
      return _compile(
        mainUri,
        request.outputPath,
        additionalSourceUri: additionalSourceUri,
        nativeAssetsUri: nativeAssets,
      );
    }
    final String inputKey = Uuid().generateV4();

    if (nativeAssets != null && nativeAssets.isNotEmpty) {
      server.stdin.writeln('native-assets $nativeAssets');
      _logger.printTrace('<- native-assets $nativeAssets');
    }
    if (request.recompileRestart) {
      server.stdin.writeln('recompile-restart $mainUri $inputKey');
    } else {
      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 _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,
    String? nativeAssetsUri,
  }) async {
    final TargetPlatform? platform = (targetModel == TargetModel.dartdevc)
        ? TargetPlatform.web_javascript
        : null;
    late final List<String> commandToStartFrontendServer;
    if (frontendServerStarterPath != null && frontendServerStarterPath!.isNotEmpty) {
      commandToStartFrontendServer = <String>[
        artifacts.getArtifactPath(Artifact.engineDartBinary, platform: platform),
        frontendServerStarterPath!,
      ];
    } else {
      commandToStartFrontendServer = <String>[
        artifacts.getArtifactPath(Artifact.engineDartAotRuntime, platform: platform),
        artifacts.getArtifactPath(
          Artifact.frontendServerSnapshotForEngineDartSdk,
          platform: platform,
        ),
      ];
    }

    final command = <String>[
      ...commandToStartFrontendServer,
      '--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',
      if (includeUnsupportedPlatformLibraryStubs) '--include-unsupported-platform-library-stubs',
      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 (nativeAssetsUri != null) ...<String>['--native-assets', nativeAssetsUri],
      if (platformDill != null) ...<String>['--platform', platformDill!],
      // See: https://github.com/flutter/flutter/issues/103994
      '--verbosity=error',
      ...?_filterExtraFrontEndOptions(extraFrontEndOptions),
    ];
    _logger.printTrace(command.join(' '));
    _server = await _processManager.start(command);
    _server?.stdout
        .transform(utf8LineDecoder)
        .listen(
          _stdoutHandler.handler,
          onDone: () {
            // when outputFilename future is not completed, but stdout is closed
            // process has died unexpectedly.
            if (_stdoutHandler.compilerOutput?.isCompleted == false &&
                !_shutdownHooks.isShuttingDown) {
              _stdoutHandler.compilerOutput?.complete();
              throwToolExit('The Dart compiler exited unexpectedly.');
            }
          },
        );

    _server?.stderr.transform(utf8LineDecoder).listen(_logger.printError);

    unawaited(
      _server?.exitCode.then((int code) {
        // The frontend server exits with a 253 error code when we shutdown due to a signal.
        // Don't treat this as an error if we're in the middle of the shutdown sequence.
        if (code != 0 && !_shutdownHooks.isShuttingDown) {
          throwToolExit('The Dart compiler exited unexpectedly.');
        }
      }),
    );

    if (nativeAssetsUri != null && nativeAssetsUri.isNotEmpty) {
      _server?.stdin.writeln('native-assets $nativeAssetsUri');
      _logger.printTrace('<- native-assets $nativeAssetsUri');
    }

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

    return _stdoutHandler.compilerOutput?.future;
  }

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

    final completer = Completer<CompilerOutput?>();
    final request = _CompileExpressionRequest(
      completer,
      expression,
      definitions,
      definitionTypes,
      typeDefinitions,
      typeBounds,
      typeDefaults,
      libraryUri,
      klass,
      method,
      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.definitionTypes?.forEach(server.stdin.writeln);
    server.stdin.writeln(inputKey);
    request.typeDefinitions?.forEach(server.stdin.writeln);
    server.stdin.writeln(inputKey);
    request.typeBounds?.forEach(server.stdin.writeln);
    server.stdin.writeln(inputKey);
    request.typeDefaults?.forEach(server.stdin.writeln);
    server.stdin
      ..writeln(inputKey)
      ..writeln(request.libraryUri ?? '')
      ..writeln(request.klass ?? '')
      ..writeln(request.method ?? '')
      ..writeln(request.isStatic);

    return _stdoutHandler.compilerOutput?.future;
  }

  @override
  Future<CompilerOutput?> compileExpressionToJs(
    String libraryUri,
    String scriptUri,
    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 = Completer<CompilerOutput?>();
    _controller.add(
      _CompileExpressionToJsRequest(
        completer,
        libraryUri,
        scriptUri,
        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;
    }

    server.stdin
      ..writeln('JSON_INPUT')
      ..writeln(
        json.encode({
          'type': 'COMPILE_EXPRESSION_JS',
          'data': {
            'expression': request.expression,
            'libraryUri': request.libraryUri,
            'scriptUri': request.scriptUri,
            'line': request.line,
            'column': request.column,
            'jsModules': request.jsModules,
            'jsFrameValues': request.jsFrameValues,
            'moduleName': request.moduleName,
          },
        }),
      );

    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 = 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 fileSystemRoot in fileSystemRoots) {
    if (filePath.startsWith(fileSystemRoot)) {
      return '$scheme://${filePath.substring(fileSystemRoot.length)}';
    }
  }
  return fileUri.toString();
}
