// 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 deprecatedJsInterop = argResults.flag('deprecated-js-interop');
  var target = DevCompilerTarget(
    TargetFlags(trackCreationLocations: trackCreationLocations),
    deprecatedJsInterop: deprecatedJsInterop,
  );
  var oldCompilerState = _reusableCompilerState(compilerState, target);
  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,
      target,
      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',
        'deprecatedJsInterop=$deprecatedJsInterop',
        'multiRootScheme=${fileSystem.markerScheme}',
        'multiRootRoots=${fileSystem.roots}',
      },
      doneAdditionalDillModules,
      compileSdk,
      sourcePathToUri(getSdkPath()),
      compileSdk ? null : sourcePathToUri(sdkSummaryPath!),
      packageFile != null ? sourcePathToUri(packageFile) : null,
      sourcePathToUri(librarySpecPath),
      additionalDillModules,
      inputDigests,
      target,
      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));
    var encodedSourceMap = jsCode.encodedSourceMap;
    if (encodedSourceMap != null) {
      outFiles.add(File('$output.map').writeAsString('$encodedSourceMap\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));
    var encodedSourceMap = jsCode.encodedSourceMap;
    if (encodedSourceMap != null) {
      outFiles.add(File('$output.map').writeAsString(encodedSourceMap));
    }
  }
  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-encoded source map, if generated, otherwise `null`.
  final String? encodedSourceMap;

  /// The decoded JSON of [encodedSourceMap], if generated, otherwise `null`.
  ///
  /// Decoded lazily on first access. Prefer [encodedSourceMap] to avoid
  /// unnecessary decoding.
  late final Map<String, Object?>? sourceMap = encodedSourceMap == null
      ? null
      : json.decode(encodedSourceMap!) as Map<String, Object?>;

  /// 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.encodedSourceMap, {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);

  // 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
    // attach it to the last library in the bundle.
    text = _replaceLast(
      text,
      LibraryCompiler.metricsLocationID,
      '${encodedMap.length}',
    );
  } else {
    var compileTimeStatistics = {
      'dartSize': _computeDartSize(component!),
      'sourceMapSize': encodedMap.length,
    };
    text = _replaceLast(
      text,
      ProgramCompiler.metricsLocationID,
      '$compileTimeStatistics',
    );
  }

  var rawSourceMap = inlineSourceMap
      ? js.escapedString(encodedMap, "'").value
      : 'null';
  text = _replaceLast(text, ProgramCompiler.sourceMapLocationID, rawSourceMap);

  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 == null ? null : encodedMap,
    symbols: debugSymbols,
    metadata: debugMetadata,
  );
}

/// Replaces the last occurrence of [from] with [to] in [text].
String _replaceLast(String text, String from, String to) {
  var index = text.lastIndexOf(from);
  if (index == -1) return text;
  return text.replaceRange(index, index + from.length, to);
}

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

/// Returns [state] if it can be reused when compiling with [target], or `null`
/// otherwise.
///
/// The CFE reuses non-incremental compiler state, including its target,
/// without comparing targets. State created for a target with a different
/// [DevCompilerTarget.deprecatedJsInterop] value would resolve `dart.library.*`
/// conditions incorrectly, so it must be discarded.
fe.InitializedCompilerState? _reusableCompilerState(
  fe.InitializedCompilerState? state,
  DevCompilerTarget target,
) {
  var oldTarget = state?.options.target;
  if (oldTarget is DevCompilerTarget &&
      oldTarget.deprecatedJsInterop != target.deprecatedJsInterop) {
    return null;
  }
  return state;
}

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