// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:convert' show json;
import 'dart:io';

import 'package:args/args.dart';
import 'package:build_integration/file_system/multi_root.dart';
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
import 'package:kernel/binary/ast_from_binary.dart'
    as kernel
    show BinaryBuilder;
import 'package:kernel/binary/ast_to_binary.dart' as kernel show BinaryPrinter;
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:kernel/text/ast_to_text.dart' as kernel show Printer;
import 'package:kernel/text/debug_printer.dart';
import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as p;
import 'package:source_maps/source_maps.dart' show SourceMapBuilder;

import '../compiler/js_names.dart' as js_ast;
import '../compiler/module_builder.dart';
import '../js_ast/js_ast.dart' as js_ast;
import '../js_ast/js_ast.dart' show js;
import '../js_ast/source_map_printer.dart' show SourceMapPrintingContext;
import '../kernel/compiler.dart';
import '../kernel/compiler_new.dart';
import '../kernel/hot_reload_delta_inspector.dart';
import '../kernel/kernel_helpers.dart';
import '../kernel/module_metadata.dart';
import '../kernel/module_symbols.dart';
import '../kernel/module_symbols_collector.dart';
import '../kernel/target.dart';
import 'arguments.dart';
import 'options.dart';
import 'result.dart';

const _binaryName = 'dartdevc';

/// Invoke the compiler with [args].
///
/// Returns a [CompilerResult], with a success flag indicating whether the
/// program compiled without any fatal errors.
///
/// The result may also contain a [previousResult], which can be passed back in
/// for batch/worker executions to attempt to existing state.
Future<CompilerResult> compile(
  ParsedArguments args, {
  fe.InitializedCompilerState? compilerState,
  Map<Uri, List<int>>? inputDigests,
}) {
  if (compilerState != null && !args.isBatchOrWorker) {
    throw ArgumentError(
      'previousResult requires --batch or --bazel_worker mode/',
    );
  }
  try {
    return _compile(
      args.rest,
      compilerState: compilerState,
      isWorker: args.isWorker,
      useIncrementalCompiler: args.useIncrementalCompiler,
      inputDigests: inputDigests,
    );
  } catch (error, stackTrace) {
    print('''
We're sorry, you've found a bug in our compiler.
You can report this bug at:
    https://github.com/dart-lang/sdk/issues/labels/web-dev-compiler
Please include the information below in your report, along with
any other information that may help us track it down. Thanks!
-------------------- %< --------------------
    $_binaryName arguments: ${args.rest.join(' ')}
    dart --version: ${Platform.version}

$error
$stackTrace
''');
    return Future.value(CompilerResult(70));
  }
}

String _usageMessage(ArgParser ddcArgParser) =>
    'The Dart Development Compiler compiles Dart sources into a JavaScript '
    'module.\n\n'
    'Usage: $_binaryName [options...] <sources...>\n\n'
    '${ddcArgParser.usage}';

Future<CompilerResult> _compile(
  List<String> args, {
  fe.InitializedCompilerState? compilerState,
  bool isWorker = false,
  bool useIncrementalCompiler = false,
  Map<Uri, List<int>>? inputDigests,
}) async {
  var argParser = Options.nonSdkArgParser();
  var declaredVariables = parseAndRemoveDeclaredVariables(args);
  ArgResults argResults;
  try {
    argResults = argParser.parse(filterUnknownArguments(args, argParser));
  } on FormatException catch (error) {
    print(error);
    print(_usageMessage(argParser));
    return CompilerResult(64);
  }
  if (argResults.wasParsed('sound-null-safety')) {
    var soundNullSafety = argResults.flag('sound-null-safety');
    print(
      'Dart 3 only supports sound null safety, '
      'see https://dart.dev/null-safety.\n'
      'The `--sound-null-safety` flag is ignored '
      'and will be removed in a future version.',
    );
    if (!soundNullSafety) {
      return CompilerResult(64);
    }
  }

  var outPaths = argResults.multiOption('out');
  var moduleFormats = parseModuleFormatOption(argResults);
  if (outPaths.isEmpty) {
    print(
      'Please specify the output file location. For example:\n'
      '    -o PATH/TO/OUTPUT_FILE.js',
    );
    return CompilerResult(64);
  } else if (outPaths.length != moduleFormats.length) {
    print(
      'Number of output files (${outPaths.length}) must match '
      'number of module formats (${moduleFormats.length}).',
    );
    return CompilerResult(64);
  }

  if (argResults.flag('help') || args.isEmpty) {
    print(_usageMessage(argParser));
    return CompilerResult(0);
  }

  var options = Options.fromArguments(argResults);
  addGeneratedVariables(
    declaredVariables,
    enableAsserts: options.enableAsserts,
  );

  Uri toCustomUri(Uri uri) {
    if (!uri.hasScheme) {
      return Uri(scheme: options.multiRootScheme, path: '/${uri.path}');
    }
    return uri;
  }

  // TODO(jmesserly): this is a workaround for the CFE, which does not
  // understand relative URIs, and we'd like to avoid absolute file URIs
  // being placed in the summary if possible.
  // TODO(jmesserly): investigate if Analyzer has a similar issue.
  Uri sourcePathToCustomUri(String source) {
    return toCustomUri(sourcePathToRelativeUri(source));
  }

  // Compile SDK module directly from a provided .dill file.
  var inputs = [for (var arg in argResults.rest) sourcePathToCustomUri(arg)];
  if (inputs.length == 1 && inputs.single.path.endsWith('.dill')) {
    return compileSdkFromDill(args);
  }

  // To make the output .dill agnostic of the current working directory,
  // we use a custom-uri scheme for all app URIs (these are files outside the
  // lib folder). The following [FileSystem] will resolve those references to
  // the correct location and keeps the real file location hidden from the
  // front end.
  var multiRootPaths = argResults
      .multiOption('multi-root')
      .map(Uri.base.resolve)
      .toList();
  var multiRootOutputPath = options.multiRootOutputPath;
  if (multiRootOutputPath == null) {
    if (outPaths.length > 1) {
      print(
        'If multiple output files (found ${outPaths.length}) are specified, '
        'then --multi-root-output-path must be explicitly provided.',
      );
      return CompilerResult(64);
    }
    var jsOutputUri = sourcePathToUri(p.absolute(outPaths.first));
    multiRootOutputPath = _longestPrefixingPath(jsOutputUri, multiRootPaths);
  }

  var fileSystem = MultiRootFileSystem(
    options.multiRootScheme,
    multiRootPaths,
    fe.StandardFileSystem.instance,
  );
  var summaryPaths = options.summaryModules.keys.toList();
  var summaryModules = Map.fromIterables(
    summaryPaths.map(sourcePathToUri).cast<Uri>(),
    options.summaryModules.values,
  );
  var sdkSummaryPath = argResults.option('dart-sdk-summary');
  var librarySpecPath = argResults.option('libraries-file');
  var compileSdk = argResults.flag('compile-sdk');
  if (sdkSummaryPath == null) {
    if (!compileSdk) {
      sdkSummaryPath = defaultSdkSummaryPath;
      librarySpecPath ??= defaultLibrarySpecPath;
    }
    // Compiling without manually passing or getting a default SDK summary is
    // only allowed when `compileSdk` is true.
  }
  var invalidSummary =
      summaryPaths.any((s) => !s.endsWith('.dill')) ||
      (sdkSummaryPath != null && !sdkSummaryPath.endsWith('.dill'));
  if (invalidSummary) {
    throw StateError('Non-dill file detected in input: $summaryPaths');
  }

  if (librarySpecPath == null) {
    // TODO(jmesserly): the `isSupported` bit should be included in the SDK
    // summary, but front_end requires a separate file, so we have to work
    // around that, while not requiring yet another command line option.
    //
    // Right now we search two locations: one level above the SDK summary
    // (this works for the build and SDK layouts) or next to the SDK summary
    // (if the user is doing something custom).
    //
    // Another option: we could make an in-memory file with the relevant info.
    librarySpecPath = p.join(
      p.dirname(p.dirname(sdkSummaryPath ?? defaultSdkSummaryPath)),
      'libraries.json',
    );
    if (!File(librarySpecPath).existsSync()) {
      librarySpecPath = p.join(
        p.dirname(sdkSummaryPath ?? defaultSdkSummaryPath),
        'libraries.json',
      );
    }
  }

  /// The .dart_tool/package_config.json file path provided by the user.
  //
  // TODO(jmesserly): the default location is based on the current working
  // directory, to match the behavior of dartanalyzer/dartdevc. However the
  // Dart VM, CFE (and dart2js?) use the script file location instead. The
  // difference may be due to the lack of a single entry point for Analyzer.
  // Ultimately this is just the default behavior; in practice users call DDC
  // through a build tool, which generally passes in `--packages=`.
  //
  // TODO(jmesserly): conceptually CFE should not need a
  // .dart_tool/package_config.json file to resolve package URIs that are in the
  // input summaries, but it seems to.
  // This needs further investigation.
  var packageFile = argResults.option('packages') ?? _findPackagesFilePath();

  var succeeded = true;
  void diagnosticMessageHandler(fe.CfeDiagnosticMessage message) {
    if (message.severity == fe.CfeSeverity.error) {
      succeeded = false;
    }
    fe.printDiagnosticMessage(message, print);
  }

  var explicitExperimentalFlags = fe.parseExperimentalFlags(
    options.experiments,
    onError: stderr.writeln,
    onWarning: print,
  );

  var trackCreationLocations = argResults.flag('track-creation-locations');
  var oldCompilerState = compilerState;
  var recordUsedInputs = argResults.option('used-inputs-file') != null;
  var additionalDillModules = summaryModules.keys.toList();
  fe.DdcResult? result;

  // TODO(jmesserly): is there a cleaner way to do this?
  //
  // Ideally we'd manage our own batch compilation caching rather than rely on
  // `initializeCompiler`. Also we should be able to pass down Components for
  // SDK and summaries.
  if (!useIncrementalCompiler) {
    compilerState = fe.initializeCompiler(
      oldCompilerState,
      compileSdk,
      sourcePathToUri(getSdkPath()),
      compileSdk ? null : sourcePathToUri(sdkSummaryPath!),
      packageFile != null ? sourcePathToUri(packageFile) : null,
      sourcePathToUri(librarySpecPath),
      additionalDillModules,
      DevCompilerTarget(
        TargetFlags(trackCreationLocations: trackCreationLocations),
      ),
      fileSystem: fileSystem,
      explicitExperimentalFlags: explicitExperimentalFlags,
      environmentDefines: declaredVariables,
    );
    result = await fe.compile(compilerState, inputs, diagnosticMessageHandler);
  } else {
    // If digests weren't given and if not in worker mode, create fake data and
    // ensure we don't have a previous state (as that wouldn't be safe with
    // fake input digests).
    inputDigests ??= {};
    if (!isWorker && inputDigests.isEmpty) {
      oldCompilerState = null;

      if (!compileSdk) {
        inputDigests[sourcePathToUri(sdkSummaryPath!)] = const [0];
      }
      for (var uri in summaryModules.keys) {
        inputDigests[uri] = const [0];
      }
    }
    var doneAdditionalDillModules = List.filled(
      summaryModules.length,
      dummyComponent,
    );
    compilerState = await fe.initializeIncrementalCompiler(
      oldCompilerState,
      {
        'trackCreationLocations=$trackCreationLocations',
        'multiRootScheme=${fileSystem.markerScheme}',
        'multiRootRoots=${fileSystem.roots}',
      },
      doneAdditionalDillModules,
      compileSdk,
      sourcePathToUri(getSdkPath()),
      compileSdk ? null : sourcePathToUri(sdkSummaryPath!),
      packageFile != null ? sourcePathToUri(packageFile) : null,
      sourcePathToUri(librarySpecPath),
      additionalDillModules,
      inputDigests,
      DevCompilerTarget(
        TargetFlags(trackCreationLocations: trackCreationLocations),
      ),
      fileSystem: fileSystem,
      explicitExperimentalFlags: explicitExperimentalFlags,
      environmentDefines: declaredVariables,
      trackNeededDillLibraries: recordUsedInputs,
    );
    var incrementalCompiler = compilerState.incrementalCompiler!;
    var cachedSdkInput = compileSdk
        ? null
        : compilerState.workerInputCache![sourcePathToUri(sdkSummaryPath!)];
    compilerState.options.onDiagnostic = diagnosticMessageHandler;
    var incrementalCompilerResult = await incrementalCompiler.computeDelta(
      entryPoints: inputs,
      fullComponent: true,
      trackNeededDillLibraries: recordUsedInputs,
    );
    result = fe.DdcResult(
      incrementalCompilerResult.component,
      cachedSdkInput?.component,
      doneAdditionalDillModules,
      incrementalCompilerResult.classHierarchy,
      incrementalCompilerResult.neededDillLibraries,
    );
  }
  compilerState.options.onDiagnostic = null; // See http://dartbug.com/36983.

  if (result == null || !succeeded) {
    return CompilerResult(1, kernelState: compilerState);
  }

  var component = result.component;
  var compiledLibraries = result.compiledLibraries;

  final reloadDeltaKernel = options.reloadDeltaKernel;
  final reloadLastAcceptedKernel = options.reloadLastAcceptedKernel;
  if (reloadDeltaKernel != null) {
    if (reloadLastAcceptedKernel != null) {
      final lastAcceptedComponent = Component();
      kernel.BinaryBuilder(
        (await File(reloadLastAcceptedKernel).readAsBytes()),
      ).readComponent(lastAcceptedComponent);
      final deltaInspector = HotReloadDeltaInspector(
        nonHotReloadablePackages: options.nonHotReloadablePackages,
      );
      final rejectionReasons = deltaInspector.compareGenerations(
        lastAcceptedComponent,
        compiledLibraries,
      );
      if (rejectionReasons.isNotEmpty) {
        throw StateError(
          'Hot reload rejected due to:\n${rejectionReasons.join('\n')}\n'
          'Try performing a hot restart instead.',
        );
      }
    }
    var sink = File(reloadDeltaKernel).openWrite();
    kernel.BinaryPrinter(
      sink,
      includeSources: false,
      includeSourceBytes: false,
    ).writeComponentFile(compiledLibraries);
    await sink.flush();
    await sink.close();
  } else {
    if (reloadLastAcceptedKernel != null) {
      throw ArgumentError(
        "Must provide 'reload-delta-kernel' if "
        "'reload-last-accepted-kernel' provided.",
      );
    }
  }

  // Output files can be written in parallel, so collect the futures.
  var outFiles = <Future>[];
  if (argResults.flag('summarize')) {
    if (outPaths.length > 1) {
      print(
        'If multiple output files (found ${outPaths.length}) are specified, '
        'the --summarize option is not supported.',
      );
      return CompilerResult(64);
    }
    // Note: CFE mutates the Kernel tree, so we can't save the dill
    // file if we successfully reused a cached library. If compiler state is
    // unchanged, it means we used the cache.
    //
    // In that case, we need to unbind canonical names, because they could be
    // bound already from the previous compile.
    if (identical(compilerState, oldCompilerState)) {
      component.unbindCanonicalNames();
    }
    var sink = File('${p.withoutExtension(outPaths.first)}.dill').openWrite();
    // TODO(jmesserly): this appears to save external libraries.
    // Do we need to run them through an outlining step so they can be saved?
    kernel.BinaryPrinter(sink).writeComponentFile(component);
    outFiles.add(sink.flush().then((_) => sink.close()));
  }
  String? fullDillUri;
  if (argResults.flag('experimental-output-compiled-kernel')) {
    if (outPaths.length > 1) {
      print(
        'If multiple output files (found ${outPaths.length}) are specified, '
        'the --experimental-output-compiled-kernel option is not supported.',
      );
      return CompilerResult(64);
    }
    // Note: CFE mutates the Kernel tree, so we can't save the dill
    // file if we successfully reused a cached library. If compiler state is
    // unchanged, it means we used the cache.
    //
    // In that case, we need to unbind canonical names, because they could be
    // bound already from the previous compile.
    if (identical(compilerState, oldCompilerState)) {
      compiledLibraries.unbindCanonicalNames();
    }
    fullDillUri = '${p.withoutExtension(outPaths.first)}.full.dill';
    var sink = File(fullDillUri).openWrite();
    kernel.BinaryPrinter(sink).writeComponentFile(compiledLibraries);
    outFiles.add(sink.flush().then((_) => sink.close()));
  }
  if (argResults.flag('summarize-text')) {
    if (outPaths.length > 1) {
      print(
        'If multiple output files (found ${outPaths.length}) are specified, '
        'the --summarize-text option is not supported.',
      );
      return CompilerResult(64);
    }
    var sb = StringBuffer();
    kernel.Printer(sb).writeComponentFile(component);
    outFiles.add(File('${outPaths.first}.txt').writeAsString(sb.toString()));
    outFiles.add(
      File(
        '${outPaths.first.split('.')[0]}.ast.xml',
      ).writeAsString(DebugPrinter.prettyPrint(compiledLibraries)),
    );
  }

  final importToSummary = Map<Library, Component>.identity();
  final summaryToModule = Map<Component, String>.identity();
  for (var i = 0; i < result.additionalDillModules.length; i++) {
    var additionalDillModule = result.additionalDillModules[i];
    var moduleImport = summaryModules[additionalDillModules[i]]!;
    for (var l in additionalDillModule.libraries) {
      assert(!importToSummary.containsKey(l));
      importToSummary[l] = additionalDillModule;
      summaryToModule[additionalDillModule] = moduleImport;
    }
  }

  // Add main component libraries to import-to-module resolution.
  //
  // This is only required for non-SDK modules, as SDK modules are all bundled
  // in the same module and are never deferred.
  // `result.component` contains all the compiled libraries as well as libraries
  // already seen in `additionalDillModules`.
  if (!compileSdk) {
    for (var l in result.component.libraries) {
      // Don't override libraries already recorded in `additionalDillModules`.
      if (importToSummary.containsKey(l)) {
        continue;
      }
      final isDartLibrary = l.importUri.isScheme('dart');
      final resolvedModuleName = isDartLibrary
          ? js_ast.dartSdkModule
          : options.moduleName;
      final resolvedComponent = isDartLibrary
          ? result.sdkSummary!
          : result.component;

      importToSummary[l] = resolvedComponent;
      summaryToModule.putIfAbsent(resolvedComponent, () => resolvedModuleName);
    }
  }

  var compiler = options.emitLibraryBundle
      ? LibraryBundleCompiler(
          component,
          result.classHierarchy,
          options,
          importToSummary,
          summaryToModule,
        )
      : ProgramCompiler(
          component,
          result.classHierarchy,
          options,
          importToSummary,
          summaryToModule,
        );

  var jsModule = compiler.emitModule(compiledLibraries);

  // Also the old Analyzer backend had some code to make debugging better when
  // --single-out-file is used, but that option does not appear to be used by
  // any of our build systems.
  for (var i = 0; i < outPaths.length; ++i) {
    var output = outPaths[i];
    var moduleFormat = moduleFormats[i];
    var file = File(output);
    await file.parent.create(recursive: true);
    var mapUrl = p.toUri('$output.map').toString();
    var jsCode = jsProgramToCode(
      jsModule,
      options.emitLibraryBundle ? ModuleFormat.ddcLibraryBundle : moduleFormat,
      buildSourceMap: options.sourceMap,
      inlineSourceMap: options.inlineSourceMap,
      emitDebugMetadata: options.emitDebugMetadata,
      emitDebugSymbols: options.emitDebugSymbols,
      jsUrl: p.toUri(output).toString(),
      mapUrl: mapUrl,
      fullDillUri: fullDillUri,
      customScheme: options.multiRootScheme,
      multiRootOutputPath: multiRootOutputPath,
      compiler: compiler,
      component: compiledLibraries,
    );

    outFiles.add(file.writeAsString(jsCode.code));
    if (jsCode.sourceMap != null) {
      outFiles.add(
        File('$output.map').writeAsString('${json.encode(jsCode.sourceMap)}\n'),
      );
    }
    if (jsCode.metadata != null) {
      outFiles.add(
        File(
          '$output.metadata',
        ).writeAsString('${json.encode(jsCode.metadata)}\n'),
      );
    }

    if (jsCode.symbols != null) {
      outFiles.add(
        File(
          '$output.symbols',
        ).writeAsString('${json.encode(jsCode.symbols)}\n'),
      );
    }
  }

  if (recordUsedInputs) {
    var usedOutlines = <Uri>{};
    if (useIncrementalCompiler) {
      var neededDillLibraries = result.neededDillLibraries!;
      compilerState.incrementalCompiler!.updateNeededDillLibrariesWithHierarchy(
        neededDillLibraries,
        result.classHierarchy,
      );
      for (var lib in neededDillLibraries) {
        if (lib.importUri.isScheme('dart')) continue;
        var uri = compilerState.libraryToInputDill![lib.importUri];
        if (uri == null) {
          throw StateError(
            'Library ${lib.importUri} was recorded as used, '
            'but was not in the list of known libraries.',
          );
        }
        usedOutlines.add(uri);
      }
    } else {
      // Used inputs wasn't recorded: Say we used everything.
      usedOutlines.addAll(summaryModules.keys);
    }

    var outputUsedFile = File(argResults.option('used-inputs-file')!);
    outputUsedFile.createSync(recursive: true);
    outputUsedFile.writeAsStringSync(usedOutlines.join('\n'));
  }

  await Future.wait(outFiles);
  return CompilerResult(0, kernelState: compilerState);
}

// A simplified entrypoint similar to `_compile` that only supports building the
// sdk. Note that some changes in `_compile_` might need to be copied here as
// well.
// TODO(sigmund): refactor the underlying pieces to reduce the code duplication.
Future<CompilerResult> compileSdkFromDill(List<String> args) async {
  var argParser = ArgParser(allowTrailingOptions: true);
  Options.addSdkRequiredArguments(argParser);

  ArgResults argResults;
  try {
    argResults = argParser.parse(filterUnknownArguments(args, argParser));
  } on FormatException catch (error) {
    print(error);
    print(_usageMessage(argParser));
    return CompilerResult(64);
  }

  var inputs = argResults.rest.toList();
  if (inputs.length != 1) {
    print(
      'Only a single input file is supported to compile the sdk from dill'
      'but found: \n${inputs.join('\n')}',
    );
    return CompilerResult(64);
  }

  if (!inputs.single.endsWith('.dill')) {
    print('Input must be a .dill file: ${inputs.single}');
    return CompilerResult(64);
  }

  var outPaths = argResults.multiOption('out');
  var moduleFormats = parseModuleFormatOption(argResults);
  if (outPaths.isEmpty) {
    print(
      'Please specify the output file location. For example:\n'
      '    -o PATH/TO/OUTPUT_FILE.js',
    );
    return CompilerResult(64);
  } else if (outPaths.length != moduleFormats.length) {
    print(
      'Number of output files (${outPaths.length}) must match '
      'number of module formats (${moduleFormats.length}).',
    );
    return CompilerResult(64);
  }

  var component = loadComponentFromBinary(inputs.single);
  var invalidLibraries = <Uri>[];
  for (var library in component.libraries) {
    if (!library.importUri.isScheme('dart')) {
      invalidLibraries.add(library.importUri);
    }
  }

  if (invalidLibraries.isNotEmpty) {
    print(
      'Only the SDK libraries can be compiled from .dill but found:\n'
      '${invalidLibraries.join('\n')}',
    );
    return CompilerResult(64);
  }
  var coreTypes = CoreTypes(component);
  var hierarchy = ClassHierarchy(component, coreTypes);
  var options = Options.fromSdkRequiredArguments(argResults);

  var compiler = options.emitLibraryBundle
      ? LibraryBundleCompiler(
          component,
          hierarchy,
          options,
          const {},
          const {},
          coreTypes: coreTypes,
        )
      : ProgramCompiler(
          component,
          hierarchy,
          options,
          const {},
          const {},
          coreTypes: coreTypes,
        );
  var jsModule = compiler.emitModule(component);
  var outFiles = <Future>[];

  // Also the old Analyzer backend had some code to make debugging better when
  // --single-out-file is used, but that option does not appear to be used by
  // any of our build systems.
  for (var i = 0; i < outPaths.length; ++i) {
    var output = outPaths[i];
    var moduleFormat = moduleFormats[i];
    var file = File(output);
    await file.parent.create(recursive: true);
    var jsCode = jsProgramToCode(
      jsModule,
      options.emitLibraryBundle ? ModuleFormat.ddcLibraryBundle : moduleFormat,
      buildSourceMap: options.sourceMap,
      inlineSourceMap: options.inlineSourceMap,
      jsUrl: p.toUri(output).toString(),
      mapUrl: p.toUri('$output.map').toString(),
      customScheme: options.multiRootScheme,
      multiRootOutputPath: options.multiRootOutputPath,
      component: component,
    );

    outFiles.add(file.writeAsString(jsCode.code));
    if (jsCode.sourceMap != null) {
      outFiles.add(
        File('$output.map').writeAsString(json.encode(jsCode.sourceMap)),
      );
    }
  }
  await Future.wait(outFiles);
  return CompilerResult(0);
}

/// Compute code size to embed in the generated JavaScript for this module.
int _computeDartSize(Component component) {
  var dartSize = 0;
  for (var lib in component.libraries) {
    dartSize += lib.dartSize;
  }
  return dartSize;
}

/// The output of compiling a JavaScript module in a particular format.
/// This was copied from module_compiler.dart class "JSModuleCode".
class JSCode {
  /// The JavaScript code for this module.
  ///
  /// If a [sourceMap] is available, this will include the `sourceMappingURL`
  /// comment at end of the file.
  final String code;

  /// The JSON of the source map, if generated, otherwise `null`.
  ///
  /// The source paths will initially be absolute paths. They can be adjusted
  /// using [placeSourceMap].
  final Map<String, Object?>? sourceMap;

  /// Module and library information
  ///
  /// The [metadata] is a contract between compiler and the debugger,
  /// helping the debugger map between libraries, modules, source paths.
  /// see: https://goto.google.com/dart-web-debugger-metadata
  final ModuleMetadata? metadata;

  /// Module debug symbols.
  ///
  /// The [symbols] is a contract between compiler and the debugger,
  /// helping the debugger map between dart and JS objects.
  final ModuleSymbols? symbols;

  JSCode(this.code, this.sourceMap, {this.symbols, this.metadata});
}

/// Converts [moduleTree] to [JSCode], using [format].
///
/// See [placeSourceMap] for a description of [sourceMapBase], [customScheme],
/// [multiRootOutputPath] and [packageConfig] arguments.
JSCode jsProgramToCode(
  js_ast.Program moduleTree,
  ModuleFormat format, {
  bool buildSourceMap = false,
  bool inlineSourceMap = false,
  bool emitDebugMetadata = false,
  bool emitDebugSymbols = false,
  String? jsUrl,
  String? mapUrl,
  String? fullDillUri,
  String? sourceMapBase,
  String? customScheme,
  String? multiRootOutputPath,
  Compiler? compiler,
  Component? component,
  PackageConfig? packageConfig,
}) {
  var opts = js_ast.JavaScriptPrintingOptions(
    allowKeywordsInProperties: true,
    allowSingleLineIfStatements: true,
  );
  js_ast.SimpleJavaScriptPrintingContext printer;
  SourceMapBuilder? sourceMap;
  if (buildSourceMap) {
    var sourceMapContext = SourceMapPrintingContext();
    sourceMap = sourceMapContext.sourceMap;
    printer = sourceMapContext;
  } else {
    printer = js_ast.SimpleJavaScriptPrintingContext();
  }

  var tree = transformModuleFormat(format, moduleTree);
  var nameListener = emitDebugSymbols ? js_ast.NameListener() : null;
  tree.accept(
    js_ast.Printer(
      opts,
      printer,
      localNamer: js_ast.ScopedNamer(tree, nameListener),
    ),
  );

  Map<String, Object?>? builtMap;
  if (buildSourceMap && sourceMap != null) {
    builtMap = placeSourceMap(
      sourceMap.build(jsUrl!),
      mapUrl!,
      customScheme,
      multiRootOutputPath: multiRootOutputPath,
      sourceMapBase: sourceMapBase,
      packageConfig: packageConfig,
    );
    var jsDir = p.dirname(p.fromUri(jsUrl));
    var relative = p.relative(p.fromUri(mapUrl), from: jsDir);
    var relativeMapUrl = p.toUri(relative).toString();
    assert(p.dirname(jsUrl) == p.dirname(mapUrl));
    printer.emit('\n//# sourceMappingURL=');
    printer.emit(relativeMapUrl);
    printer.emit('\n');
  }

  var text = printer.getText();
  var encodedMap = json.encode(builtMap);
  var rawSourceMap = inlineSourceMap
      ? js.escapedString(encodedMap, "'").value
      : 'null';
  text = text.replaceFirst(ProgramCompiler.sourceMapLocationID, rawSourceMap);

  // This is intended to be used by our build/debug tools to gather metrics.
  // See pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js for runtime code that
  // reads this.
  //
  // These keys (see corresponding logic in ddc_module_loader.js) include:
  // - dartSize: <size of Dart input code in bytes>
  // - sourceMapSize: <size of JS source map in bytes>
  //
  // TODO(vsm): Ideally, this information is never sent to the browser.  I.e.,
  // our runtime metrics gathering would obtain this information from the
  // compilation server, not the browser.  We don't yet have the infra for that.
  if (ModuleFormat.ddcLibraryBundle == format) {
    // TODO(nshahan): Find a better solution for the size of the source map
    // per library. For now we just use the size of the full source map and only
    // count it once in the runtime when the first library gets defined.
    text = text.replaceFirst(
      ProgramCompiler.metricsLocationID,
      '${encodedMap.length}',
    );
    text = text.replaceAll(LibraryCompiler.metricsLocationID, '0');
  } else {
    var compileTimeStatistics = {
      'dartSize': _computeDartSize(component!),
      'sourceMapSize': encodedMap.length,
    };
    text = text.replaceFirst(
      ProgramCompiler.metricsLocationID,
      '$compileTimeStatistics',
    );
  }

  var debugMetadata = emitDebugMetadata
      ? _emitMetadata(moduleTree, component!, mapUrl!, jsUrl!, fullDillUri)
      : null;

  var debugSymbols = emitDebugSymbols
      ? _emitSymbols(
          compiler!,
          moduleTree.name!,
          nameListener!.identifierNames,
          component!,
        )
      : null;

  return JSCode(text, builtMap, symbols: debugSymbols, metadata: debugMetadata);
}

/// Assembles symbol information describing the nodes from the AST [component]
/// and their representation in JavaScript.
///
/// Uses information from the [compiler] used to compile the JS module combined
/// with [identifierNames] that maps JavaScript identifier nodes to their actual
/// names used when outputting the JavaScript.
ModuleSymbols _emitSymbols(
  Compiler compiler,
  String moduleName,
  Map<js_ast.Identifier, String> identifierNames,
  Component component,
) {
  /// Returns the name selected in the final JavaScript for [id].
  String lookupName(js_ast.Identifier id) {
    var name = identifierNames[id];
    if (name == null) {
      throw Exception(
        'No recorded naming decision found for Identifier with '
        'name: ${id.name}',
      );
    }
    return name;
  }

  var classJsNames = <Class, String>{
    for (var e in compiler.classIdentifiers.entries) e.key: lookupName(e.value),
  };
  var procedureJsNames = <Procedure, String>{
    for (var e in compiler.procedureIdentifiers.entries)
      e.key: lookupName(e.value),
  };
  var variableJsNames = <Variable, String>{
    for (var e in compiler.variableIdentifiers.entries)
      e.key: lookupName(e.value),
  };

  return ModuleSymbolsCollector(
    moduleName,
    classJsNames,
    compiler.memberNames,
    procedureJsNames,
    variableJsNames,
  ).collectSymbolInfo(component);
}

ModuleMetadata _emitMetadata(
  js_ast.Program program,
  Component component,
  String sourceMapUri,
  String moduleUri,
  String? fullDillUri,
) {
  var metadata = ModuleMetadata(
    program.name!,
    loadFunctionName(program.name!),
    sourceMapUri,
    moduleUri,
    fullDillUri,
  );

  for (var lib in component.libraries) {
    metadata.addLibrary(
      LibraryMetadata(
        libraryUriToJsIdentifier(lib.importUri),
        lib.importUri.toString(),
        lib.fileUri.toString(),
        [...lib.parts.map((p) => p.partUri)],
      ),
    );
  }
  return metadata;
}

/// Parses Dart's non-standard `-Dname=value` syntax for declared variables,
/// and removes them from [args] so the result can be parsed normally.
Map<String, String> parseAndRemoveDeclaredVariables(List<String> args) {
  var declaredVariables = <String, String>{};
  for (var i = 0; i < args.length;) {
    var arg = args[i];
    String? rest;
    const defineFlag = '--define';
    if (arg.startsWith('-D') && arg.length > 2) {
      rest = arg.substring(2);
    } else if (arg.startsWith('$defineFlag=') &&
        arg.length > defineFlag.length + 1) {
      rest = arg.substring(defineFlag.length + 1);
    } else if (arg == defineFlag) {
      i++;
      rest = args[i];
    }

    if (rest != null) {
      var eq = rest.indexOf('=');
      if (eq <= 0) {
        var kind = eq == 0 ? 'name' : 'value';
        throw FormatException('no $kind given to -D option `$arg`');
      }
      var name = rest.substring(0, eq);
      var value = rest.substring(eq + 1);
      declaredVariables[name] = value;
      args.removeAt(i);
    } else {
      i++;
    }
  }

  return declaredVariables;
}

/// Adds all synthesized environment variables to [variables].
Map<String, String> addGeneratedVariables(
  Map<String, String> variables, {
  required bool enableAsserts,
}) {
  variables['dart.web.assertions_enabled'] = '$enableAsserts';
  return variables;
}

/// The default path of the kernel summary for the Dart SDK.
final defaultSdkSummaryPath = p.join(
  getSdkPath(),
  'lib',
  '_internal',
  'ddc_outline.dill',
);

final defaultLibrarySpecPath = p.join(getSdkPath(), 'lib', 'libraries.json');

/// Return the path to the runtime Dart SDK.
String getSdkPath() {
  // Support explicit sdk location through an environment variable.
  var resolvedExecutable = Platform.environment['resolvedExecutable'];
  return p.dirname(
    p.dirname(resolvedExecutable ?? Platform.resolvedExecutable),
  );
}

/// Returns the absolute path to the default `package_config.json` file, or
/// `null` if one could not be found.
///
/// Checks for a `.dart_tool/package_config.json` file in the current working
/// directory, or in any parent directory.
String? _findPackagesFilePath() {
  // TODO(jmesserly): this was copied from package:package_config/discovery.dart
  // Unfortunately the relevant function is not public. CFE APIs require a URI
  // to the .dart_tool/package_config.json file, rather than letting us provide
  // the package map data.
  var dir = Directory.current;
  if (!dir.isAbsolute) dir = dir.absolute;
  if (!dir.existsSync()) return null;

  // Check for $cwd/.dart_tool/package_config.json
  while (true) {
    var file = File.fromUri(dir.uri.resolve('.dart_tool/package_config.json'));
    if (file.existsSync()) return file.path;

    // If we didn't find it, search the parent directory.
    // Stop the search if we're already at the root.
    var parent = dir.parent;
    if (dir.path == parent.path) return null;
    dir = parent;
  }
}

/// Inputs must be absolute paths. Returns null if no prefixing path is found.
String? _longestPrefixingPath(Uri baseUri, List<Uri> prefixingPaths) {
  var basePath = baseUri.path;
  return prefixingPaths.fold(null, (String? previousValue, Uri element) {
    if (basePath.startsWith(element.path) &&
        (previousValue == null || previousValue.length < element.path.length)) {
      return element.path;
    }
    return previousValue;
  });
}

/// Convert a [source] string to a Uri, where the source may be a
/// dart/file/package URI or a local win/mac/linux path.
Uri sourcePathToUri(String source, {bool? windows}) {
  if (windows == null) {
    // Running on the web the Platform check will fail, and we can't use
    // fromEnvironment because internally it's set to true for dart.library.io.
    // So just catch the exception and if it fails then we're definitely not on
    // Windows.
    try {
      windows = Platform.isWindows;
    } catch (e) {
      windows = false;
    }
  }
  if (windows) {
    source = source.replaceAll('\\', '/');
  }

  var result = Uri.base.resolve(source);
  if (windows && result.scheme.length == 1) {
    // Assume c: or similar --- interpret as file path.
    return Uri.file(source, windows: true);
  }
  return result;
}

Uri sourcePathToRelativeUri(String source, {bool? windows}) {
  var uri = sourcePathToUri(source, windows: windows);
  if (uri.isScheme('file')) {
    var uriPath = uri.path;
    var root = Uri.base.path;
    if (uriPath.startsWith(root)) {
      return p.toUri(uriPath.substring(root.length));
    }
  }
  return uri;
}

/// Pattern to match when a relative path appears to leave the `lib/` directory
/// of one package to enter the `lib/` directory of another package.
final _crossPackageLib = RegExp(
  // Two or more '../'.
  r'\.\.\/(?:\.\.\/)+'
  // The package name (captured).
  r'([^\/]*)'
  // The `/lib/` directory.
  r'\/lib\/',
);

/// Adjusts the source uris in [sourceMap] to be relative uris, and returns
/// the new map.
///
/// Source uris show up in two forms, absolute `file:` uris and custom
/// [multiRootScheme] uris (also "absolute" uris, but always relative to some
/// multi-root).
///
/// - `file:` uris are converted to be relative to [sourceMapBase], which
///   defaults to the dirname of [sourceMapPath] if not provided.
///
/// - [multiRootScheme] uris are prefixed by [multiRootOutputPath]. If the
///   path starts with `/lib`, then we strip that before making it relative
///   to the [multiRootOutputPath], and assert that [multiRootOutputPath]
///   starts with `/packages` (more explanation inline).
///
/// Passing a [packageConfig] will enable the rewriting of original source paths
/// when the sourcemap contains files from `lib/` directories across multiple
/// packages. The rewriting assumes that the sources will be served in a package
/// directory structure without `lib/` directories.
///
// TODO(#40251): Remove this logic from dev_compiler itself, push it to the
// invokers of dev_compiler which have more knowledge about how they want
// source paths to look.
Map<String, Object?> placeSourceMap(
  Map<String, Object?> sourceMap,
  String sourceMapPath,
  String? multiRootScheme, {
  String? multiRootOutputPath,
  String? sourceMapBase,
  PackageConfig? packageConfig,
}) {
  var map = Map.of(sourceMap);
  // Convert to a local file path if it's not.
  sourceMapPath = sourcePathToUri(p.absolute(p.fromUri(sourceMapPath))).path;
  var sourceMapDir = p.url.dirname(sourceMapPath);
  sourceMapBase ??= sourceMapDir;
  var basePackageName = packageConfig?.packageOf(p.toUri(sourceMapBase))?.name;
  var list = (map['sources'] as List).toList();

  String makeRelative(String sourcePath) {
    var uri = sourcePathToUri(sourcePath);
    var scheme = uri.scheme;
    if (scheme == 'dart' || scheme == 'package' || scheme == multiRootScheme) {
      if (scheme == multiRootScheme) {
        // TODO(sigmund): extract all source-map normalization outside ddc. This
        // custom logic is BUILD specific and could be shared with other tools
        // like dart2js.
        var shortPath = uri.path.replaceAll('/sdk/', '/dart-sdk/');
        var multiRootPath = "${multiRootOutputPath ?? ''}$shortPath";
        multiRootPath = p.url.joinAll(
          p.split(p.relative(multiRootPath, from: sourceMapDir)),
        );
        return multiRootPath;
      }
      return sourcePath;
    }

    if (uri.isScheme('http')) return sourcePath;

    // Convert to a local file path if it's not.
    sourcePath = sourcePathToUri(p.absolute(p.fromUri(uri))).path;

    // Fall back to a relative path against the source map itself.
    sourcePath = p.url.relative(sourcePath, from: sourceMapBase);

    // Convert from relative local path to relative URI.
    var relativeUriPath = p.toUri(sourcePath).path;
    // Handle source paths when the original sources come from the `lib/`
    // directories from different packages.
    //
    // This assumes that the original source files and source map will be hosted
    // in a packages directory structure with all of the `lib/` directories
    // removed.
    // For reference:
    //  - https://github.com/dart-lang/sdk/issues/40251
    //  - https://github.com/dart-lang/webdev/issues/1692
    if (basePackageName != null && uri.isScheme('file')) {
      var sourcePackage = packageConfig?.packageOf(uri);
      if (sourcePackage != null && basePackageName != sourcePackage.name) {
        // The source location is part of a different package.
        var match = _crossPackageLib.matchAsPrefix(relativeUriPath);
        if (match != null) {
          var crossPackageName = match[1];
          return relativeUriPath.replaceFirst(
            '../../$crossPackageName/lib/',
            '../$crossPackageName/',
          );
        }
      }
    }
    return relativeUriPath;
  }

  for (var i = 0; i < list.length; i++) {
    list[i] = makeRelative(list[i] as String);
  }
  map['sources'] = list;
  map['file'] = map['file'] != null
      ? makeRelative(map['file'] as String)
      : null;
  return map;
}
