// Copyright (c) 2016, 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.

library front_end.compiler_options;

import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
    show DiagnosticMessage, DiagnosticMessageHandler;
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;

import 'package:kernel/ast.dart' show Version;

import 'package:kernel/default_language_version.dart' as kernel
    show defaultLanguageVersion;

import 'package:kernel/target/targets.dart' show Target;

import '../base/nnbd_mode.dart';

import 'experimental_flags.dart'
    show
        AllowedExperimentalFlags,
        defaultExperimentalFlags,
        ExperimentalFlag,
        expiredExperimentalFlags,
        parseExperimentalFlag;

import 'experimental_flags.dart' as flags
    show
        getExperimentEnabledVersionInLibrary,
        isExperimentEnabled,
        isExperimentEnabledInLibrary,
        isExperimentEnabledInLibraryByVersion;

import 'file_system.dart' show FileSystem;

import 'standard_file_system.dart' show StandardFileSystem;

import '../api_unstable/util.dart';

export 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
    show DiagnosticMessage;

/// Front-end options relevant to compiler back ends.
///
/// Not intended to be implemented or extended by clients.
class CompilerOptions {
  /// The URI of the root of the Dart SDK (typically a "file:" URI).
  ///
  /// If `null`, the SDK will be searched for using
  /// [Platform.resolvedExecutable] as a starting point.
  Uri? sdkRoot;

  /// Uri to a platform libraries specification file.
  ///
  /// A libraries specification file is a JSON file that describes how to map
  /// `dart:*` libraries to URIs in the underlying [fileSystem].  See
  /// `package:front_end/src/base/libraries_specification.dart` for details on
  /// the format.
  ///
  /// If a value is not specified and `compileSdk = true`, the compiler will
  /// infer at a default location under [sdkRoot], typically under
  /// `lib/libraries.json`.
  Uri? librariesSpecificationUri;

  DiagnosticMessageHandler? onDiagnostic;

  /// URI of the ".dart_tool/package_config.json" or ".packages" file
  /// (typically a "file:" URI).
  ///
  /// If a ".packages" file is given and a ".dart_tool/package_config.json" file
  /// exists next to it, the ".dart_tool/package_config.json" file is used
  /// instead.
  ///
  /// If `null`, the file will be found via the standard package_config search
  /// algorithm.
  ///
  /// If the URI's path component is empty (e.g. `new Uri()`), no packages file
  /// will be used.
  Uri? packagesFileUri;

  /// URIs of additional dill files.
  ///
  /// These will be loaded and linked into the output.
  ///
  /// The components provided here should be closed: any libraries that they
  /// reference should be defined in a component in [additionalDills] or
  /// [sdkSummary].
  List<Uri> additionalDills = [];

  /// URI of the SDK summary file (typically a "file:" URI).
  ///
  /// This should should be a summary previously generated by this package (and
  /// not the similarly named summary files from `package:analyzer`.)
  ///
  /// If `null` and [compileSdk] is false, the SDK summary will be searched for
  /// at a default location within [sdkRoot].
  Uri? sdkSummary;

  /// The declared variables for use by configurable imports and constant
  /// evaluation.
  Map<String, String>? declaredVariables;

  /// The [FileSystem] which should be used by the front end to access files.
  ///
  /// All file system access performed by the front end goes through this
  /// mechanism, with one exception: if no value is specified for
  /// [packagesFileUri], the packages file is located using the actual physical
  /// file system.  TODO(paulberry): fix this.
  FileSystem fileSystem = StandardFileSystem.instance;

  /// Whether to generate code for the SDK.
  ///
  /// By default the front end resolves components using a prebuilt SDK summary.
  /// When this option is `true`, [sdkSummary] must be null.
  bool compileSdk = false;

  /// Enable or disable experimental features. Features mapping to `true` are
  /// explicitly enabled. Features mapping to `false` are explicitly disabled.
  /// Features not mentioned in the map will have their default value.
  Map<ExperimentalFlag, bool> explicitExperimentalFlags =
      <ExperimentalFlag, bool>{};

  Map<ExperimentalFlag, bool>? defaultExperimentFlagsForTesting;
  AllowedExperimentalFlags? allowedExperimentalFlagsForTesting;
  Map<ExperimentalFlag, Version>? experimentEnabledVersionForTesting;
  Map<ExperimentalFlag, Version>? experimentReleasedVersionForTesting;

  /// Environment map used when evaluating `bool.fromEnvironment`,
  /// `int.fromEnvironment` and `String.fromEnvironment` during constant
  /// evaluation. If the map is `null`, all environment constants will be left
  /// unevaluated and can be evaluated by a constant evaluator later.
  Map<String, String>? environmentDefines = null;

  /// Report an error if a constant could not be evaluated (either because it
  /// is an environment constant and no environment was specified, or because
  /// it refers to a constructor or variable initializer that is not available).
  bool errorOnUnevaluatedConstant = false;

  /// The target platform that will consume the compiled code.
  ///
  /// Used to provide platform-specific details to the compiler like:
  ///   * the set of libraries are part of a platform's SDK (e.g. dart:html for
  ///     dart2js, dart:ui for flutter).
  ///
  ///   * what kernel transformations should be applied to the component
  ///     (async/await, mixin inlining, etc).
  ///
  ///   * how to deal with non-standard features like `native` extensions.
  ///
  /// If not specified, the default target is the VM.
  Target? target;

  /// Whether to show verbose messages (mainly for debugging and performance
  /// tracking).
  ///
  /// Messages are printed on stdout.
  // TODO(sigmund): improve the diagnostics API to provide mechanism to
  // intercept verbose data (Issue #30056)
  bool verbose = false;

  /// Whether to run extra verification steps to validate that compiled
  /// components are well formed.
  ///
  /// Errors are reported via the [onDiagnostic] callback.
  bool verify = false;

  /// Whether to - if verifying - skip the platform.
  bool skipPlatformVerification = false;

  /// Whether to dump generated components in a text format (also mainly for
  /// debugging).
  ///
  /// Dumped data is printed in stdout.
  bool debugDump = false;

  /// Whether to omit the platform when serializing the result from a `fasta
  /// compile` run.
  bool omitPlatform = false;

  /// Whether to set the exit code to non-zero if any problem (including
  /// warning, etc.) is encountered during compilation.
  bool setExitCodeOnProblem = false;

  /// Whether to embed the input sources in generated kernel components.
  ///
  /// The kernel `Component` API includes a `uriToSource` map field that is used
  /// to embed the entire contents of the source files. This part of the kernel
  /// API is in flux and it is not necessary for some tools. Today it is used
  /// for translating error locations and stack traces in the VM.
  // TODO(sigmund): change the default.
  bool embedSourceText = true;

  /// Whether the compiler should throw as soon as it encounters a
  /// compilation error.
  ///
  /// Typically used by developers to debug internals of the compiler.
  bool throwOnErrorsForDebugging = false;

  /// Whether the compiler should throw as soon as it encounters a
  /// compilation warning.
  ///
  /// Typically used by developers to debug internals of the compiler.
  bool throwOnWarningsForDebugging = false;

  /// For the [throwOnErrorsForDebugging] or [throwOnWarningsForDebugging]
  /// options, skip this number of otherwise fatal diagnostics without throwing.
  /// I.e. the default value of 0 means throw on the first fatal diagnostic.
  ///
  /// If the value is negative, print a stack trace for every fatal
  /// diagnostic, but do not stop the compilation.
  int skipForDebugging = 0;

  /// Whether to write a file (e.g. a dill file) when reporting a crash.
  bool writeFileOnCrashReport = true;

  /// Whether nnbd weak, strong or agnostic mode is used if experiment
  /// 'non-nullable' is enabled.
  NnbdMode nnbdMode = NnbdMode.Weak;

  /// Whether to emit a warning when a ReachabilityError is thrown to ensure
  /// soundness in mixed mode.
  bool warnOnReachabilityCheck = false;

  /// The current sdk version string, e.g. "2.6.0-edge.sha1hash".
  /// For instance used for language versioning (specifying the maximum
  /// version).
  String currentSdkVersion = "${kernel.defaultLanguageVersion.major}"
      "."
      "${kernel.defaultLanguageVersion.minor}";

  /// If `true`, a '.d' file with input dependencies is generated when
  /// compiling the platform dill.
  bool emitDeps = true;

  /// Set of invocation modes the describe how the compilation is performed.
  ///
  /// This used to selectively emit certain messages depending on how the
  /// CFE is invoked. For instance to emit a message about the null safety
  /// compilation mode when the modes includes [InvocationMode.compile].
  Set<InvocationMode> invocationModes = {};

  /// Verbosity level used for filtering emitted messages.
  Verbosity verbosity = Verbosity.all;

  /// Returns `true` if the experiment with the given [flag] is enabled, either
  /// explicitly or implicitly.
  ///
  /// Note that libraries can still opt out of the experiment by having a lower
  /// language version than required for the experiment.
  bool isExperimentEnabled(ExperimentalFlag flag) {
    return flags.isExperimentEnabled(flag,
        explicitExperimentalFlags: explicitExperimentalFlags,
        defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting);
  }

  /// Returns `true` if the experiment with the given [flag] is enabled either
  /// explicitly or implicitly for the library with the given [importUri].
  ///
  /// Note that the library can still opt out of the experiment by having a
  /// lower language version than required for the experiment. See
  /// [getExperimentEnabledVersionInLibrary].
  bool isExperimentEnabledInLibrary(ExperimentalFlag flag, Uri importUri) {
    return flags.isExperimentEnabledInLibrary(flag, importUri,
        defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting,
        explicitExperimentalFlags: explicitExperimentalFlags,
        allowedExperimentalFlags: allowedExperimentalFlagsForTesting);
  }

  /// Returns the minimum language version needed for a library with the given
  /// [importUri] to opt in to the experiment with the given [flag].
  ///
  /// Note that the experiment might not be enabled at all for the library, as
  /// computed by [isExperimentEnabledInLibrary].
  Version getExperimentEnabledVersionInLibrary(
      ExperimentalFlag flag, Uri importUri) {
    return flags.getExperimentEnabledVersionInLibrary(
        flag, importUri, explicitExperimentalFlags,
        defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting,
        allowedExperimentalFlags: allowedExperimentalFlagsForTesting,
        experimentEnabledVersionForTesting: experimentEnabledVersionForTesting,
        experimentReleasedVersionForTesting:
            experimentReleasedVersionForTesting);
  }

  /// Return `true` if the experiment with the given [flag] is enabled for the
  /// library with the given [importUri] and language [version].
  bool isExperimentEnabledInLibraryByVersion(
      ExperimentalFlag flag, Uri importUri, Version version) {
    return flags.isExperimentEnabledInLibraryByVersion(flag, importUri, version,
        explicitExperimentalFlags: explicitExperimentalFlags,
        defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting,
        allowedExperimentalFlags: allowedExperimentalFlagsForTesting,
        experimentEnabledVersionForTesting: experimentEnabledVersionForTesting,
        experimentReleasedVersionForTesting:
            experimentReleasedVersionForTesting);
  }

  bool equivalent(CompilerOptions other,
      {bool ignoreOnDiagnostic: true,
      bool ignoreVerbose: true,
      bool ignoreVerify: true,
      bool ignoreDebugDump: true}) {
    if (sdkRoot != other.sdkRoot) return false;
    if (librariesSpecificationUri != other.librariesSpecificationUri) {
      return false;
    }
    if (!ignoreOnDiagnostic) {
      if (onDiagnostic != other.onDiagnostic) return false;
    }
    if (packagesFileUri != other.packagesFileUri) return false;
    if (!equalLists(additionalDills, other.additionalDills)) return false;
    if (sdkSummary != other.sdkSummary) return false;
    if (!equalMaps(declaredVariables, other.declaredVariables)) return false;
    if (fileSystem != other.fileSystem) return false;
    if (compileSdk != compileSdk) return false;
    // chaseDependencies aren't used anywhere, so ignored here.
    // targetPatches aren't used anywhere, so ignored here.
    if (!equalMaps(
        explicitExperimentalFlags, other.explicitExperimentalFlags)) {
      return false;
    }
    if (!equalMaps(environmentDefines, other.environmentDefines)) return false;
    if (errorOnUnevaluatedConstant != other.errorOnUnevaluatedConstant) {
      return false;
    }
    if (target != other.target) {
      if (target.runtimeType != other.target.runtimeType) return false;
      if (target?.name != other.target?.name) return false;
      if (target?.flags != other.target?.flags) return false;
    }
    // enableAsserts is not used anywhere, so ignored here.
    if (!ignoreVerbose) {
      if (verbose != other.verbose) return false;
    }
    if (!ignoreVerify) {
      if (verify != other.verify) return false;
      if (skipPlatformVerification != other.skipPlatformVerification) {
        return false;
      }
    }
    if (!ignoreDebugDump) {
      if (debugDump != other.debugDump) return false;
    }
    if (omitPlatform != other.omitPlatform) return false;
    if (setExitCodeOnProblem != other.setExitCodeOnProblem) return false;
    if (embedSourceText != other.embedSourceText) return false;
    if (throwOnErrorsForDebugging != other.throwOnErrorsForDebugging) {
      return false;
    }
    if (throwOnWarningsForDebugging != other.throwOnWarningsForDebugging) {
      return false;
    }
    if (skipForDebugging != other.skipForDebugging) return false;
    if (writeFileOnCrashReport != other.writeFileOnCrashReport) return false;
    if (nnbdMode != other.nnbdMode) return false;
    if (currentSdkVersion != other.currentSdkVersion) return false;
    if (emitDeps != other.emitDeps) return false;
    if (!equalSets(invocationModes, other.invocationModes)) return false;

    return true;
  }
}

/// Parse experimental flag arguments of the form 'flag' or 'no-flag' into a map
/// from 'flag' to `true` or `false`, respectively.
Map<String, bool> parseExperimentalArguments(Iterable<String>? arguments) {
  Map<String, bool> result = {};
  if (arguments != null) {
    for (String argument in arguments) {
      for (String feature in argument.split(',')) {
        if (feature.startsWith('no-')) {
          result[feature.substring(3)] = false;
        } else {
          result[feature] = true;
        }
      }
    }
  }
  return result;
}

/// Parse a map of experimental flags to values that can be passed to
/// [CompilerOptions.explicitExperimentalFlags].
///
/// If an unknown flag is mentioned, or a flag is mentioned more than once,
/// the supplied error handler is called with an error message.
///
/// If an expired flag is set to its non-default value the supplied error
/// handler is called with an error message.
///
/// If an expired flag is set to its default value the supplied warning
/// handler is called with a warning message.
Map<ExperimentalFlag, bool> parseExperimentalFlags(
    Map<String, bool>? experiments,
    {required void Function(String message) onError,
    void Function(String message)? onWarning}) {
  Map<ExperimentalFlag, bool> flags = <ExperimentalFlag, bool>{};
  if (experiments != null) {
    for (String experiment in experiments.keys) {
      bool value = experiments[experiment]!;
      ExperimentalFlag? flag = parseExperimentalFlag(experiment);
      if (flag == null) {
        onError("Unknown experiment: " + experiment);
      } else if (flags.containsKey(flag)) {
        if (flags[flag] != value) {
          onError(
              "Experiment specified with conflicting values: " + experiment);
        }
      } else {
        if (expiredExperimentalFlags[flag]!) {
          if (value != defaultExperimentalFlags[flag]) {
            /// Produce an error when the value is not the default value.
            if (value) {
              onError("Enabling experiment " +
                  experiment +
                  " is no longer supported.");
            } else {
              onError("Disabling experiment " +
                  experiment +
                  " is no longer supported.");
            }
            value = defaultExperimentalFlags[flag]!;
          } else if (onWarning != null) {
            /// Produce a warning when the value is the default value.
            if (value) {
              onWarning("Experiment " +
                  experiment +
                  " is enabled by default. "
                      "The use of the flag is deprecated.");
            } else {
              onWarning("Experiment " +
                  experiment +
                  " is disabled by default. "
                      "The use of the flag is deprecated.");
            }
          }
          flags[flag] = value;
        } else {
          flags[flag] = value;
        }
      }
    }
  }
  return flags;
}

class InvocationMode {
  /// This mode is used for when the CFE is invoked in order to compile an
  /// executable.
  ///
  /// If used, a message about the null safety compilation mode will be emitted.
  static const InvocationMode compile = const InvocationMode('compile');

  final String name;

  const InvocationMode(this.name);

  /// Returns the set of information modes from a comma-separated list of
  /// invocation mode names.
  ///
  /// If a name isn't recognized and [onError] is provided, [onError] is called
  /// with an error messages and an empty set of invocation modes is returned.
  ///
  /// If a name isn't recognized and [onError] isn't provided, an error is
  /// thrown.
  static Set<InvocationMode> parseArguments(String arg,
      {void Function(String)? onError}) {
    Set<InvocationMode> result = {};
    for (String name in arg.split(',')) {
      if (name.isNotEmpty) {
        InvocationMode? mode = fromName(name);
        if (mode == null) {
          String message = "Unknown invocation mode '$name'.";
          if (onError != null) {
            onError(message);
          } else {
            throw new UnsupportedError(message);
          }
        } else {
          result.add(mode);
        }
      }
    }
    return result;
  }

  /// Returns the [InvocationMode] with the given [name].
  static InvocationMode? fromName(String name) {
    for (InvocationMode invocationMode in values) {
      if (name == invocationMode.name) {
        return invocationMode;
      }
    }
    return null;
  }

  static const List<InvocationMode> values = const [compile];
}

/// Verbosity level used for filtering messages during compilation.
class Verbosity {
  /// Only error messages are emitted.
  static const Verbosity error =
      const Verbosity('error', 'Show only error messages');

  /// Error and warning messages are emitted.
  static const Verbosity warning =
      const Verbosity('warning', 'Show only error and warning messages');

  /// Error, warning, and info messages are emitted.
  static const Verbosity info =
      const Verbosity('info', 'Show error, warning, and info messages');

  /// All messages are emitted.
  static const Verbosity all = const Verbosity('all', 'Show all messages');

  static const List<Verbosity> values = const [error, warning, info, all];

  /// Returns the names of all options.
  static List<String> get allowedValues =>
      [for (Verbosity value in values) value.name];

  /// Returns a map from option name to option help messages.
  static Map<String, String> get allowedValuesHelp =>
      {for (Verbosity value in values) value.name: value.help};

  /// Returns the verbosity corresponding to the given [name].
  ///
  /// If [name] isn't recognized and [onError] is provided, [onError] is called
  /// with an error messages and [defaultValue] is returned.
  ///
  /// If [name] isn't recognized and [onError] isn't provided, an error is
  /// thrown.
  static Verbosity parseArgument(String name,
      {void Function(String)? onError, Verbosity defaultValue: Verbosity.all}) {
    for (Verbosity verbosity in values) {
      if (name == verbosity.name) {
        return verbosity;
      }
    }
    String message = "Unknown verbosity '$name'.";
    if (onError != null) {
      onError(message);
      return defaultValue;
    }
    throw new UnsupportedError(message);
  }

  static bool shouldPrint(Verbosity verbosity, DiagnosticMessage message) {
    Severity severity = message.severity;
    switch (verbosity) {
      case Verbosity.error:
        switch (severity) {
          case Severity.internalProblem:
          case Severity.error:
            return true;
          case Severity.warning:
          case Severity.info:
          case Severity.context:
          case Severity.ignored:
            return false;
        }
      case Verbosity.warning:
        switch (severity) {
          case Severity.internalProblem:
          case Severity.error:
          case Severity.warning:
            return true;
          case Severity.info:
          case Severity.context:
          case Severity.ignored:
            return false;
        }
      case Verbosity.info:
        switch (severity) {
          case Severity.internalProblem:
          case Severity.error:
          case Severity.warning:
          case Severity.info:
            return true;
          case Severity.context:
          case Severity.ignored:
            return false;
        }
      case Verbosity.all:
        return true;
    }
    throw new UnsupportedError(
        "Unsupported verbosity $verbosity and severity $severity.");
  }

  static const String defaultValue = 'all';

  final String name;
  final String help;

  const Verbosity(this.name, this.help);

  @override
  String toString() => 'Verbosity($name)';
}
