// 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 trackWidgetCreation = argResults.flag('track-widget-creation');
  var oldCompilerState = compilerState;
  var recordUsedInputs = argResults.option('used-inputs-file') != null;
  var additionalDills = 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),
      additionalDills,
      DevCompilerTarget(TargetFlags(trackWidgetCreation: trackWidgetCreation)),
      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 doneAdditionalDills = List.filled(
      summaryModules.length,
      dummyComponent,
    );
    compilerState = await fe.initializeIncrementalCompiler(
      oldCompilerState,
      {
        'trackWidgetCreation=$trackWidgetCreation',
        'multiRootScheme=${fileSystem.markerScheme}',
        'multiRootRoots=${fileSystem.roots}',
      },
      doneAdditionalDills,
      compileSdk,
      sourcePathToUri(getSdkPath()),
      compileSdk ? null : sourcePathToUri(sdkSummaryPath!),
      packageFile != null ? sourcePathToUri(packageFile) : null,
      sourcePathToUri(librarySpecPath),
      additionalDills,
      inputDigests,
      DevCompilerTarget(TargetFlags(trackWidgetCreation: trackWidgetCreation)),
      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,
      doneAdditionalDills,
      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.additionalDills.length; i++) {
    var additionalDill = result.additionalDills[i];
    var moduleImport = summaryModules[additionalDills[i]]!;
    for (var l in additionalDill.libraries) {
      assert(!importToSummary.containsKey(l));
      importToSummary[l] = additionalDill;
      summaryToModule[additionalDill] = 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 `additionalDills`.
  if (!compileSdk) {
    for (var l in result.component.libraries) {
      // Don't override libraries already recorded in `additionalDills`.
      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 = <VariableDeclaration, 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.group(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;
}
