// 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 'package:args/args.dart';

import 'package:front_end/src/api_unstable/ddc.dart'
    show parseExperimentalArguments;
import 'package:path/path.dart' as p;

import '../compiler/module_builder.dart';

/// Compiler options for the `dartdevc` backend.
class Options {
  /// Whether to emit the source mapping file.
  ///
  /// This supports debugging the original source code instead of the generated
  /// code.
  final bool sourceMap;

  /// Whether to emit the source mapping file in the program text, so the
  /// runtime can enable synchronous stack trace deobfuscation.
  final bool inlineSourceMap;

  /// Whether to emit the full compiled kernel.
  ///
  /// This is used by expression compiler worker, launched from the debugger
  /// in webdev and google3 scenarios, for expression evaluation features.
  /// Full kernel for compiled files is needed to be able to compile
  /// expressions on demand in the current scope of a breakpoint.
  final bool emitFullCompiledKernel;

  final String? reloadLastAcceptedKernel;
  final String? reloadDeltaKernel;

  /// Whether to emit a summary file containing API signatures.
  ///
  /// This is required for a modular build process.
  final bool summarizeApi;

  // Whether to enable assertions.
  final bool enableAsserts;

  /// Whether to compile code in a more permissive REPL mode allowing access
  /// to private members across library boundaries.
  ///
  /// This should only set `true` by our REPL compiler.
  bool replCompile;

  /// Whether to emit the debug metadata
  ///
  /// Debugger uses this information about to construct mapping between
  /// modules and libraries that otherwise requires expensive communication with
  /// the browser.
  final bool emitDebugMetadata;

  /// Whether to emit the debug symbols
  ///
  /// Debugger uses this information about to construct mapping between
  /// dart and js objects that otherwise requires expensive communication with
  /// the browser.
  final bool emitDebugSymbols;

  final Map<String, String> summaryModules;

  final List<ModuleFormat> moduleFormats;

  /// The name of the module.
  ///
  /// This is used to support file concatenation. The JS module will contain its
  /// module name inside itself, allowing it to declare the module name
  /// independently of the file.
  final String moduleName;

  /// Custom scheme to indicate a multi-root uri.
  final String multiRootScheme;

  /// Path to set multi-root files relative to when generating source-maps.
  final String? multiRootOutputPath;

  /// Experimental language features that are enabled/disabled, see
  /// [the spec](https://github.com/dart-lang/sdk/blob/master/docs/process/experimental-flags.md)
  /// for more details.
  final Map<String, bool> experiments;

  /// Whether or not the `--canary` flag was specified during compilation.
  final bool canaryFeatures;

  /// When `true` the [Component] will be compiled into a format compatible with
  /// hot reload.
  ///
  /// The output will still be a single file containing each library in an
  /// isolated namespace.
  final bool emitLibraryBundle;

  /// Whether the compiler is generating a dynamic module.
  final bool dynamicModule;

  /// Raw precompiled macro options, each of the format
  /// `<program-uri>;<macro-library-uri>`.
  ///
  /// Multiple library URIs may be provided separated by additional semicolons.
  final List<String> precompiledMacros;

  /// The serialization mode to use for macro communication.
  final String? macroSerializationMode;

  Options(
      {this.sourceMap = true,
      this.inlineSourceMap = false,
      this.summarizeApi = true,
      this.enableAsserts = true,
      this.replCompile = false,
      this.emitDebugMetadata = false,
      this.emitDebugSymbols = false,
      this.emitFullCompiledKernel = false,
      this.reloadLastAcceptedKernel,
      this.reloadDeltaKernel,
      this.summaryModules = const {},
      this.moduleFormats = const [],
      required this.moduleName,
      this.multiRootScheme = 'org-dartlang-app',
      this.multiRootOutputPath,
      this.experiments = const {},
      this.canaryFeatures = false,
      this.dynamicModule = false,
      this.precompiledMacros = const [],
      this.macroSerializationMode})
      : emitLibraryBundle = canaryFeatures &&
            moduleFormats.length == 1 &&
            moduleFormats.single == ModuleFormat.ddc;

  Options.fromArguments(ArgResults args)
      : this(
            sourceMap: args['source-map'] as bool,
            inlineSourceMap: args['inline-source-map'] as bool,
            summarizeApi: args['summarize'] as bool,
            enableAsserts: args['enable-asserts'] as bool,
            replCompile: args['repl-compile'] as bool,
            emitDebugMetadata: args['experimental-emit-debug-metadata'] as bool,
            emitDebugSymbols: args['emit-debug-symbols'] as bool,
            emitFullCompiledKernel:
                args['experimental-output-compiled-kernel'] as bool,
            reloadLastAcceptedKernel:
                args['reload-last-accepted-kernel'] as String?,
            reloadDeltaKernel: args['reload-delta-kernel'] as String?,
            summaryModules:
                _parseCustomSummaryModules(args['summary'] as List<String>),
            moduleFormats: parseModuleFormatOption(args),
            moduleName: _getModuleName(args),
            multiRootScheme: args['multi-root-scheme'] as String,
            multiRootOutputPath: args['multi-root-output-path'] as String?,
            experiments: parseExperimentalArguments(
                args['enable-experiment'] as List<String>),
            canaryFeatures: args['canary'] as bool,
            dynamicModule: args['dynamic-module'] as bool,
            precompiledMacros: args['precompiled-macro'] as List<String>,
            macroSerializationMode:
                args['macro-serialization-mode'] as String?);

  Options.fromSdkRequiredArguments(ArgResults args)
      : this(
            summarizeApi: false,
            moduleFormats: parseModuleFormatOption(args),
            // When compiling the SDK use dart_sdk as the default. This is the
            // assumed name in various places around the build systems.
            moduleName:
                args['module-name'] != null ? _getModuleName(args) : 'dart_sdk',
            multiRootScheme: args['multi-root-scheme'] as String,
            multiRootOutputPath: args['multi-root-output-path'] as String?,
            experiments: parseExperimentalArguments(
                args['enable-experiment'] as List<String>),
            canaryFeatures: args['canary'] as bool);

  static void addArguments(ArgParser parser, {bool hide = true}) {
    addSdkRequiredArguments(parser, hide: hide);

    parser
      ..addMultiOption('summary',
          abbr: 's',
          help: 'API summary file(s) of imported libraries, optionally\n'
              'with module import path: -s path.dill=js/import/path')
      ..addFlag('summarize',
          help: 'Emit an API summary file.', defaultsTo: true, hide: hide)
      ..addFlag('source-map',
          help: 'Emit source mapping.', defaultsTo: true, hide: hide)
      ..addFlag('inline-source-map',
          help: 'Emit source mapping inline.', defaultsTo: false, hide: hide)
      ..addFlag('enable-asserts',
          help: 'Enable assertions.', defaultsTo: true, hide: hide)
      ..addFlag('repl-compile',
          help: 'Compile in a more permissive REPL mode, allowing access'
              ' to private members across library boundaries. This should'
              ' only be used by debugging tools.',
          defaultsTo: false,
          hide: hide)
      // TODO(41852) Define a process for breaking changes before graduating from
      // experimental.
      ..addFlag('experimental-emit-debug-metadata',
          help: 'Experimental option for compiler development.\n'
              'Output a metadata file for debug tools next to the .js output.',
          defaultsTo: false,
          hide: true)
      ..addFlag('emit-debug-symbols',
          help: 'Experimental option for compiler development.\n'
              'Output a symbols file for debug tools next to the .js output.',
          defaultsTo: false,
          hide: true)
      ..addFlag('experimental-output-compiled-kernel',
          help: 'Experimental option for compiler development.\n'
              'Output a full kernel file for currently compiled module next to '
              'the .js output.',
          defaultsTo: false,
          hide: true)
      ..addOption('reload-last-accepted-kernel',
          help: 'Provides a file path to read a dill file. The enclosed kernel '
              'will be diffed against the kernel produced by this compilation '
              'as an incremental hot reload step.',
          hide: true)
      ..addOption('reload-delta-kernel',
          help: 'Provides a file path to write a dill file to. The resulting '
              'kernel can be passed to future compilations via '
              '`reload-last-accepted-kernel` to get incremental hot reload '
              'checks.',
          hide: true)
      ..addMultiOption('precompiled-macro',
          help:
              'Configuration for precompiled macro binaries or kernel files.\n'
              'The expected format of this option is as follows: '
              '<absolute-path-to-binary>;<macro-library-uri>\nFor example: '
              '--precompiled-macro="/path/to/compiled/macro;'
              'package:some_macro/some_macro.dart". Multiple library uris may be '
              'passed as well (separated by semicolons).',
          hide: true)
      ..addOption('macro-serialization-mode',
          help: 'The serialization mode for communicating with macros.',
          allowed: ['bytedata', 'json'],
          defaultsTo: 'bytedata')
      ..addFlag('dynamic-module',
          help: 'Compile to generate a dynamic module',
          negatable: false,
          defaultsTo: false);
  }

  /// Adds only the arguments used to compile the SDK from a full dill file.
  ///
  /// NOTE: The 'module-name' option will have a special default value of
  /// 'dart_sdk' when compiling the SDK.
  /// See [SharedOptions.fromSdkRequiredArguments].
  static void addSdkRequiredArguments(ArgParser parser, {bool hide = true}) {
    addModuleFormatOptions(parser, hide: hide);
    parser
      ..addMultiOption('out', abbr: 'o', help: 'Output file (required).')
      ..addOption('module-name',
          help: 'The output module name, used in some JS module formats.\n'
              'Defaults to the output file name (without .js).')
      ..addOption('multi-root-scheme',
          help: 'The custom scheme to indicate a multi-root uri.',
          defaultsTo: 'org-dartlang-app')
      ..addOption('multi-root-output-path',
          help: 'Path to set multi-root files relative to when generating'
              ' source-maps.',
          hide: true)
      ..addMultiOption('enable-experiment',
          help: 'Enable/disable experimental language features.', hide: hide)
      ..addFlag('sound-null-safety',
          help: 'Ignored and will be removed in a future version. '
              'Sound null safety is always used.',
          negatable: false,
          defaultsTo: true)
      ..addFlag('canary',
          help: 'Enable all compiler features under active development. '
              'This option is intended for compiler development only. '
              'Canary features are likely to be unstable and can be removed '
              'without warning.',
          defaultsTo: false,
          hide: true);
  }

  static String _getModuleName(ArgResults args) {
    var moduleName = args['module-name'] as String?;
    if (moduleName == null) {
      var outPaths = args['out'] as List<String>;
      if (outPaths.isEmpty) {
        throw UnsupportedError(
            'No module name provided and unable to synthesize one without any '
            'output paths.');
      }
      var outPath = outPaths.first;
      moduleName = p.basenameWithoutExtension(outPath);
    }
    // TODO(jmesserly): this should probably use sourcePathToUri.
    //
    // Also we should not need this logic if the user passed in the module name
    // explicitly. It is here for backwards compatibility until we can confirm
    // that build systems do not depend on passing windows-style paths here.
    return p.toUri(moduleName).toString();
  }
}

/// Finds explicit module names of the form `path=name` in [summaryPaths],
/// and returns the path to mapping in an ordered map from `path` to `name`.
///
/// A summary path can contain "=" followed by an explicit module name to
/// allow working with summaries whose physical location is outside of the
/// module root directory.
Map<String, String> _parseCustomSummaryModules(List<String> summaryPaths,
    [String? moduleRoot, String? summaryExt]) {
  var pathToModule = <String, String>{};
  for (var summaryPath in summaryPaths) {
    var equalSign = summaryPath.indexOf('=');
    String modulePath;
    var summaryPathWithoutExt = summaryExt != null
        ? summaryPath.substring(
            0,
            // Strip off the extension, including the last `.`.
            summaryPath.length - (summaryExt.length + 1))
        : p.withoutExtension(summaryPath);
    if (equalSign != -1) {
      modulePath = summaryPath.substring(equalSign + 1);
      summaryPath = summaryPath.substring(0, equalSign);
    } else if (moduleRoot != null && p.isWithin(moduleRoot, summaryPath)) {
      // TODO: Determine if this logic is still needed.
      modulePath = p.url.joinAll(
          p.split(p.relative(summaryPathWithoutExt, from: moduleRoot)));
    } else {
      modulePath = p.basename(summaryPathWithoutExt);
    }
    pathToModule[summaryPath] = modulePath;
  }
  return pathToModule;
}

/// Taken from analyzer to implement `--ignore-unrecognized-flags`
List<String> filterUnknownArguments(List<String> args, ArgParser parser) {
  if (!args.contains('--ignore-unrecognized-flags')) return args;

  var knownOptions = <String>{};
  var knownAbbreviations = <String>{};
  parser.options.forEach((String name, Option option) {
    knownOptions.add(name);
    var abbreviation = option.abbr;
    if (abbreviation != null) {
      knownAbbreviations.add(abbreviation);
    }
    if (option.negatable != null && option.negatable!) {
      knownOptions.add('no-$name');
    }
  });

  String optionName(int prefixLength, String arg) {
    var equalsOffset = arg.lastIndexOf('=');
    if (equalsOffset < 0) {
      return arg.substring(prefixLength);
    }
    return arg.substring(prefixLength, equalsOffset);
  }

  var filtered = <String>[];
  for (var arg in args) {
    if (arg.startsWith('--') && arg.length > 2) {
      if (knownOptions.contains(optionName(2, arg))) {
        filtered.add(arg);
      }
    } else if (arg.startsWith('-') && arg.length > 1) {
      if (knownAbbreviations.contains(optionName(1, arg))) {
        filtered.add(arg);
      }
    } else {
      filtered.add(arg);
    }
  }
  return filtered;
}
