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