// 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;
}
