// Copyright (c) 2018, 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:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:meta/meta.dart';
import 'package:pub_semver/pub_semver.dart';

/// The same as [ExperimentStatus.knownFeatures], except when a call to
/// [overrideKnownFeatures] is in progress.
Map<String, ExperimentalFeature> _knownFeatures =
    ExperimentStatus.knownFeatures;

/// This flag is `true` while [overrideKnownFeaturesAsync] is executing.
bool _overrideKnownFeaturesAsyncExecuting = false;

/// Decodes the strings given in [flags] into a list of booleans representing
/// experiments that should be enabled.
///
/// Always succeeds, even if the input flags are invalid.  Expired and
/// unrecognized flags are ignored, conflicting flags are resolved in favor of
/// the flag appearing last.
EnabledDisabledFlags decodeExplicitFlags(List<String> flags) {
  var enabledFlags = List<bool>.filled(_knownFeatures.length, false);
  var disabledFlags = List<bool>.filled(_knownFeatures.length, false);
  for (var entry in _flagStringsToMap(flags).entries) {
    if (entry.value) {
      enabledFlags[entry.key] = true;
    } else {
      disabledFlags[entry.key] = true;
    }
  }
  return EnabledDisabledFlags(enabledFlags, disabledFlags);
}

/// Pretty-prints the given set of enable flags as a set of feature names.
String experimentStatusToString(List<bool> enableFlags) {
  var featuresInSet = <String>[];
  for (var feature in _knownFeatures.values) {
    if (enableFlags[feature.index]) {
      featuresInSet.add(feature.enableString);
    }
  }
  return 'FeatureSet{${featuresInSet.join(', ')}}';
}

/// Execute the callback, pretending that the given [knownFeatures] take the
/// place of [ExperimentStatus.knownFeatures].
///
/// It isn't safe to call this method with an asynchronous callback, because it
/// only changes the set of known features during the time that [callback] is
/// (synchronously) executing. Use [overrideKnownFeaturesAsync] instead.
@visibleForTesting
T overrideKnownFeatures<T>(
  Map<String, ExperimentalFeature> knownFeatures,
  T Function() callback,
) {
  var oldKnownFeatures = _knownFeatures;
  try {
    _knownFeatures = knownFeatures;
    return callback();
  } finally {
    _knownFeatures = oldKnownFeatures;
  }
}

/// Execute the callback, pretending that the given [knownFeatures] take the
/// place of [ExperimentStatus.knownFeatures].
///
/// This function cannot be invoked before its previous invocation completes.
@visibleForTesting
Future<T> overrideKnownFeaturesAsync<T>(
  Map<String, ExperimentalFeature> knownFeatures,
  Future<T> Function() callback,
) async {
  if (_overrideKnownFeaturesAsyncExecuting) {
    throw StateError('overrideKnownFeaturesAsync is not reentrant');
  }

  _overrideKnownFeaturesAsyncExecuting = true;
  var oldKnownFeatures = _knownFeatures;
  try {
    _knownFeatures = knownFeatures;
    return await callback();
  } finally {
    _knownFeatures = oldKnownFeatures;
    _overrideKnownFeaturesAsyncExecuting = false;
  }
}

/// Computes a new set of enable flags based on [version].
///
/// Features in [explicitEnabledFlags] are enabled in the [sdkLanguageVersion].
///
/// Features in [explicitDisabledFlags] are always disabled.
List<bool> restrictEnableFlagsToVersion({
  required Version sdkLanguageVersion,
  required List<bool> explicitEnabledFlags,
  required List<bool> explicitDisabledFlags,
  required Version version,
}) {
  var decodedFlags = List.filled(_knownFeatures.length, false);
  for (var feature in _knownFeatures.values) {
    if (explicitDisabledFlags[feature.index]) {
      decodedFlags[feature.index] = false;
      continue;
    }

    var releaseVersion = feature.releaseVersion;
    if (releaseVersion != null && version >= releaseVersion) {
      decodedFlags[feature.index] = true;
    }

    if (explicitEnabledFlags[feature.index]) {
      var experimentalReleaseVersion = feature.experimentalReleaseVersion;
      if (experimentalReleaseVersion == null) {
        // Specifically, the current sdk version (whatever it is) is always
        // used as the language version which opts code into the experiment
        // when the experiment flag is passed.
        if (version == sdkLanguageVersion) {
          decodedFlags[feature.index] = true;
        }
      } else {
        // An experiment flag may at any point be assigned an experimental
        // release version.  From that point forward, all tools will no
        // longer use the current sdk version to opt code in, but rather
        // will use the experimental release version as the opt in version.
        // Updated 2020-08-25: we decided that experimental features should
        // be available since `min(sdk, experimentalRelease)`.
        if (version >= experimentalReleaseVersion ||
            version >= sdkLanguageVersion) {
          decodedFlags[feature.index] = true;
        }
      }
    }
  }

  return decodedFlags;
}

/// Validates whether there are any disagreements between the strings given in
/// [flags1] and the strings given in [flags2].
///
/// The returned iterable yields any problems that were found.  Only reports
/// problems related to combining the flags; problems that would be found by
/// applying [validateFlags] to [flags1] or [flags2] individually are not
/// reported.
///
/// If no problems are found, it is safe to concatenate the flag lists.  If
/// problems are found, the only negative side effect is that some flags in
/// one list may be overridden by some flags in the other list.
///
// TODO(paulberry): if this method ever needs to be exposed via the analyzer
// public API, consider making a version that reports validation results using
// the AnalysisError type.
Iterable<ConflictingFlagLists> validateFlagCombination(
    List<String> flags1, List<String> flags2) sync* {
  var flag1Map = _flagStringsToMap(flags1);
  var flag2Map = _flagStringsToMap(flags2);
  for (var entry in flag2Map.entries) {
    if (flag1Map[entry.key] != null && flag1Map[entry.key] != entry.value) {
      yield ConflictingFlagLists(
          _featureIndexToFeature(entry.key), !entry.value);
    }
  }
}

/// Validates whether the strings given in [flags] constitute a valid set of
/// experimental feature enable/disable flags.
///
/// The returned iterable yields any problems that were found.
///
// TODO(paulberry): if this method ever needs to be exposed via the analyzer
// public API, consider making a version that reports validation results using
// the AnalysisError type.
Iterable<ValidationResult> validateFlags(List<String> flags) sync* {
  var previousFlagIndex = <int, int>{};
  var previousFlagValue = <int, bool>{};
  for (int flagIndex = 0; flagIndex < flags.length; flagIndex++) {
    var flag = flags[flagIndex];
    ExperimentalFeature? feature;
    bool requestedValue;
    if (flag.startsWith('no-')) {
      feature = _knownFeatures[flag.substring(3)];
      requestedValue = false;
    } else {
      feature = _knownFeatures[flag];
      requestedValue = true;
    }
    if (feature == null) {
      yield UnrecognizedFlag(flagIndex, flag);
    } else if (feature.isExpired) {
      yield requestedValue == feature.isEnabledByDefault
          ? UnnecessaryUseOfExpiredFlag(flagIndex, feature)
          : IllegalUseOfExpiredFlag(flagIndex, feature);
    } else if (previousFlagIndex.containsKey(feature.index) &&
        previousFlagValue[feature.index] != requestedValue) {
      yield ConflictingFlags(flagIndex, previousFlagIndex[feature.index]!,
          feature, requestedValue);
    } else {
      previousFlagIndex[feature.index] = flagIndex;
      previousFlagValue[feature.index] = requestedValue;
    }
  }
}

ExperimentalFeature _featureIndexToFeature(int index) {
  for (var feature in _knownFeatures.values) {
    if (feature.index == index) return feature;
  }
  throw ArgumentError('Unrecognized feature index');
}

Map<int, bool> _flagStringsToMap(List<String> flags) {
  var result = <int, bool>{};
  for (int flagIndex = 0; flagIndex < flags.length; flagIndex++) {
    var flag = flags[flagIndex];
    ExperimentalFeature? feature;
    bool requestedValue;
    if (flag.startsWith('no-')) {
      feature = _knownFeatures[flag.substring(3)];
      requestedValue = false;
    } else {
      feature = _knownFeatures[flag];
      requestedValue = true;
    }
    if (feature != null && !feature.isExpired) {
      result[feature.index] = requestedValue;
    }
  }
  return result;
}

/// Indication of a conflict between two lists of flags.
class ConflictingFlagLists {
  /// Info about which feature the user requested conflicting values for
  final ExperimentalFeature feature;

  /// True if the first list of flags requested to enable the experimental
  /// feature.
  final bool firstValue;

  ConflictingFlagLists(this.feature, this.firstValue);
}

/// Validation result indicating that the user requested conflicting values for
/// an experimental flag (e.g. both "foo" and "no-foo").
class ConflictingFlags extends ValidationResult {
  /// Info about which feature the user requested conflicting values for
  final ExperimentalFeature feature;

  /// The index of the first of the two conflicting strings.
  ///
  /// [stringIndex] is the index of the second of the two conflicting strings.
  final int previousStringIndex;

  /// True if the string at [stringIndex] requested to enable the experimental
  /// feature.
  ///
  /// The string at [previousStringIndex] requested the opposite.
  final bool requestedValue;

  ConflictingFlags(super.stringIndex, this.previousStringIndex, this.feature,
      this.requestedValue)
      : super._();

  @override
  String get flag => feature.stringForValue(requestedValue);

  @override
  bool get isError => true;

  @override
  String get message {
    var previousFlag = feature.stringForValue(!requestedValue);
    return 'Flag "$flag" conflicts with previous flag "$previousFlag"';
  }
}

class EnabledDisabledFlags {
  final List<bool> enabled;
  final List<bool> disabled;

  EnabledDisabledFlags(this.enabled, this.disabled);
}

/// Information about a single experimental flag that the user might use to
/// request that a feature be enabled (or disabled).
class ExperimentalFeature implements Feature {
  /// Index of the flag in the private data structure maintained by
  /// [ExperimentStatus].
  ///
  /// This index should not be relied upon to be stable over time.  For instance
  /// it should not be used to serialize the state of experiments to long term
  /// storage if there is any expectation of compatibility between analyzer
  /// versions.
  final int index;

  /// The string to enable the feature.
  final String enableString;

  /// Whether the feature is currently enabled by default.
  final bool isEnabledByDefault;

  /// Whether the flag is currently expired (meaning the enable/disable status
  /// can no longer be altered from the value in [isEnabledByDefault]).
  final bool isExpired;

  /// Documentation for the feature, if known.  `null` for expired flags.
  final String documentation;

  /// The first language version in which this feature can be enabled using
  /// the [enableString] experimental flag.
  final Version? experimentalReleaseVersion;

  @override
  final Version? releaseVersion;

  ExperimentalFeature({
    required this.index,
    required this.enableString,
    required this.isEnabledByDefault,
    required this.isExpired,
    required this.documentation,
    required this.experimentalReleaseVersion,
    required this.releaseVersion,
  }) : assert(isEnabledByDefault
            ? releaseVersion != null
            : releaseVersion == null);

  /// The string to disable the feature.
  String get disableString => 'no-$enableString';

  @override
  String? get experimentalFlag => isExpired ? null : enableString;

  @override
  FeatureStatus get status {
    if (isExpired) {
      if (isEnabledByDefault) {
        return FeatureStatus.current;
      } else {
        return FeatureStatus.abandoned;
      }
    } else {
      if (isEnabledByDefault) {
        return FeatureStatus.provisional;
      } else {
        return FeatureStatus.future;
      }
    }
  }

  /// Retrieves the string to enable or disable the feature, depending on
  /// [value].
  String stringForValue(bool value) => value ? enableString : disableString;

  @override
  String toString() => enableString;
}

/// Validation result indicating that the user requested enabling or disabling
/// of a feature associated with an expired flag, and the requested behavior
/// conflicts with the behavior that is now hardcoded into the toolchain.
class IllegalUseOfExpiredFlag extends ValidationResult {
  /// Information about the feature associated with the error.
  final ExperimentalFeature feature;

  IllegalUseOfExpiredFlag(super.flagIndex, this.feature) : super._();

  @override
  String get flag => feature.stringForValue(!feature.isEnabledByDefault);

  @override
  bool get isError => true;

  @override
  String get message {
    var state = feature.isEnabledByDefault ? 'enabled' : 'disabled';
    return 'Flag "$flag" was supplied, but the feature is already '
        'unconditionally $state.';
  }
}

/// Validation result indicating that the user requested enabling or disabling
/// of a feature associated with an expired flag, and the requested behavior
/// is consistent with the behavior that is now hardcoded into the toolchain.
/// (This is merely a warning, not an error).
class UnnecessaryUseOfExpiredFlag extends ValidationResult {
  /// Information about the feature associated with the warning.
  final ExperimentalFeature feature;

  UnnecessaryUseOfExpiredFlag(super.flagIndex, this.feature) : super._();

  @override
  String get flag => feature.stringForValue(feature.isEnabledByDefault);

  @override
  bool get isError => false;

  @override
  String get message => 'Flag "$flag" is no longer required.';
}

/// Validation result indicating that the user requested enabling or disabling
/// an unrecognized feature.
class UnrecognizedFlag extends ValidationResult {
  @override
  final String flag;

  UnrecognizedFlag(super.flagIndex, this.flag) : super._();

  @override
  bool get isError => true;

  @override
  String get message => 'Flag "$flag" not recognized.';
}

/// Representation of a single error or warning reported by [validateFlags].
abstract class ValidationResult {
  /// Indicates which of the supplied strings is associated with the error or
  /// warning.
  final int stringIndex;

  ValidationResult._(this.stringIndex);

  /// The supplied string associated with the error or warning.
  String get flag;

  /// Indicates whether the validation result is an error or a warning.
  bool get isError;

  /// Message describing the problem.
  String get message;

  @override
  String toString() => message;
}
