// 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_impl.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:meta/meta.dart';
import 'package:pub_semver/src/version.dart';

export 'package:analyzer/src/dart/analysis/experiments_impl.dart'
    show
        ConflictingFlags,
        ExperimentalFeature,
        IllegalUseOfExpiredFlag,
        UnnecessaryUseOfExpiredFlag,
        UnrecognizedFlag,
        validateFlags,
        ValidationResult;

/// Gets access to the private list of boolean flags in an [Experiments] object.
/// For testing use only.
@visibleForTesting
List<bool> getExperimentalFlags_forTesting(ExperimentStatus status) =>
    status._enableFlags;

/// Constant strings for enabling each of the currently known experimental
/// flags.
class EnableString {
  /// String to enable the experiment "constant-update"
  static const String constant_update_2018 = 'constant-update-2018';

  /// String to enable the experiment "control-flow-collections"
  static const String control_flow_collections = 'control-flow-collections';

  /// String to enable the experiment "extension-methods"
  static const String extension_methods = 'extension-methods';

  /// String to enable the experiment "non-nullable"
  static const String non_nullable = 'non-nullable';

  /// String to enable the experiment "set-literals"
  static const String set_literals = 'set-literals';

  /// String to enable the experiment "spread-collections"
  static const String spread_collections = 'spread-collections';

  /// String to enable the experiment "triple-shift"
  static const String triple_shift = 'triple-shift';

  /// String to enable the experiment "bogus-disabled"
  static const String bogus_disabled = 'bogus-disabled';

  /// String to enable the experiment "bogus-enabled"
  static const String bogus_enabled = 'bogus-enabled';
}

class ExperimentalFeatures {
  static const constant_update_2018 = const ExperimentalFeature(
      0,
      EnableString.constant_update_2018,
      IsEnabledByDefault.constant_update_2018,
      IsExpired.constant_update_2018,
      'Q4 2018 Constant Update');

  static const non_nullable = const ExperimentalFeature(
      1,
      EnableString.non_nullable,
      IsEnabledByDefault.non_nullable,
      IsExpired.non_nullable,
      'Non Nullable');

  static const control_flow_collections = const ExperimentalFeature(
      2,
      EnableString.control_flow_collections,
      IsEnabledByDefault.control_flow_collections,
      IsExpired.control_flow_collections,
      'Control Flow Collections',
      firstSupportedVersion: '2.2.2');

  static const spread_collections = const ExperimentalFeature(
      3,
      EnableString.spread_collections,
      IsEnabledByDefault.spread_collections,
      IsExpired.spread_collections,
      'Spread Collections',
      firstSupportedVersion: '2.2.2');

  static const set_literals = const ExperimentalFeature(
      4,
      EnableString.set_literals,
      IsEnabledByDefault.set_literals,
      IsExpired.set_literals,
      'Set Literals',
      firstSupportedVersion: '2.2.0');

  static const triple_shift = const ExperimentalFeature(
      5,
      EnableString.triple_shift,
      IsEnabledByDefault.triple_shift,
      IsExpired.triple_shift,
      'Triple-shift operator');

  static const extension_methods = const ExperimentalFeature(
      6,
      EnableString.extension_methods,
      IsEnabledByDefault.extension_methods,
      IsExpired.extension_methods,
      'Extension Methods');

  static const bogus_disabled = const ExperimentalFeature(
      7,
      EnableString.bogus_disabled,
      IsEnabledByDefault.bogus_disabled,
      IsExpired.bogus_disabled,
      null);

  static const bogus_enabled = const ExperimentalFeature(
      8,
      EnableString.bogus_enabled,
      IsEnabledByDefault.bogus_enabled,
      IsExpired.bogus_enabled,
      null,
      firstSupportedVersion: '1.0.0');
}

/// A representation of the set of experiments that are active and whether they
/// are enabled.
class ExperimentStatus implements FeatureSet {
  /// A map containing information about all known experimental flags.
  static const knownFeatures = <String, ExperimentalFeature>{
    EnableString.constant_update_2018:
        ExperimentalFeatures.constant_update_2018,
    EnableString.control_flow_collections:
        ExperimentalFeatures.control_flow_collections,
    EnableString.extension_methods: ExperimentalFeatures.extension_methods,
    EnableString.non_nullable: ExperimentalFeatures.non_nullable,
    EnableString.set_literals: ExperimentalFeatures.set_literals,
    EnableString.spread_collections: ExperimentalFeatures.spread_collections,
    EnableString.triple_shift: ExperimentalFeatures.triple_shift,
    EnableString.bogus_disabled: ExperimentalFeatures.bogus_disabled,
    EnableString.bogus_enabled: ExperimentalFeatures.bogus_enabled,
  };

  final List<bool> _enableFlags;

  /// Initializes a newly created set of experiments based on optional
  /// arguments.
  ExperimentStatus(
      {bool constant_update_2018,
      bool control_flow_collections,
      bool extension_methods,
      bool non_nullable,
      bool set_literals,
      bool spread_collections,
      bool triple_shift})
      : _enableFlags = <bool>[
          constant_update_2018 ?? IsEnabledByDefault.constant_update_2018,
          non_nullable ?? IsEnabledByDefault.non_nullable,
          true, // control-flow-collections
          true, // spread-collections
          true, // set-literals
          triple_shift ?? IsEnabledByDefault.triple_shift,
          extension_methods ?? IsEnabledByDefault.extension_methods,
          false, // bogus-disabled
          true, // bogus-enabled
        ];

  /// Computes a set of features for use in a unit test.  Computes the set of
  /// features enabled in [sdkVersion], plus any specified [additionalFeatures].
  ///
  /// If [sdkVersion] is not supplied (or is `null`), then the current set of
  /// enabled features is used as the starting point.
  @visibleForTesting
  ExperimentStatus.forTesting(
      {String sdkVersion, List<Feature> additionalFeatures: const []})
      : this._(enableFlagsForTesting(
            sdkVersion: sdkVersion, additionalFeatures: additionalFeatures));

  /// Decodes the strings given in [flags] into a representation of the set of
  /// 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.
  ExperimentStatus.fromStrings(List<String> flags) : this._(decodeFlags(flags));

  ExperimentStatus._(this._enableFlags);

  /// Current state for the flag "bogus_disabled"
  bool get bogus_disabled => isEnabled(ExperimentalFeatures.bogus_disabled);

  /// Current state for the flag "bogus_enabled"
  bool get bogus_enabled => isEnabled(ExperimentalFeatures.bogus_enabled);

  /// Current state for the flag "constant-update-2018"
  bool get constant_update_2018 =>
      isEnabled(ExperimentalFeatures.constant_update_2018);

  /// Current state for the flag "control_flow_collections"
  bool get control_flow_collections =>
      isEnabled(ExperimentalFeatures.control_flow_collections);

  /// Current state for the flag "extension_methods"
  bool get extension_methods =>
      isEnabled(ExperimentalFeatures.extension_methods);

  @override
  int get hashCode {
    int hash = 0;
    for (var flag in _enableFlags) {
      hash = JenkinsSmiHash.combine(hash, flag.hashCode);
    }
    return JenkinsSmiHash.finish(hash);
  }

  /// Current state for the flag "non-nullable"
  bool get non_nullable => isEnabled(ExperimentalFeatures.non_nullable);

  /// Current state for the flag "set-literals"
  bool get set_literals => isEnabled(ExperimentalFeatures.set_literals);

  /// Current state for the flag "spread_collections"
  bool get spread_collections =>
      isEnabled(ExperimentalFeatures.spread_collections);

  /// Current state for the flag "triple_shift"
  bool get triple_shift => isEnabled(ExperimentalFeatures.triple_shift);

  @override
  operator ==(Object other) {
    if (other is ExperimentStatus) {
      if (_enableFlags.length != other._enableFlags.length) return false;
      for (int i = 0; i < _enableFlags.length; i++) {
        if (_enableFlags[i] != other._enableFlags[i]) return false;
      }
      return true;
    }
    return false;
  }

  /// Queries whether the given [feature] is enabled or disabled.
  @override
  bool isEnabled(covariant ExperimentalFeature feature) =>
      _enableFlags[feature.index];

  @override
  FeatureSet restrictToVersion(Version version) =>
      ExperimentStatus._(restrictEnableFlagsToVersion(_enableFlags, version));

  @override
  String toString() => experimentStatusToString(_enableFlags);

  /// Returns a list of strings suitable for passing to
  /// [ExperimentStatus.fromStrings].
  List<String> toStringList() => experimentStatusToStringList(this);
}

/// Constant bools indicating whether each experimental flag is currently
/// enabled by default.
class IsEnabledByDefault {
  /// Default state of the experiment "constant-update"
  static const bool constant_update_2018 = false;

  /// Default state of the experiment "control-flow-collections"
  static const bool control_flow_collections = true;

  /// Default state of the experiment "extension-methods"
  static const bool extension_methods = false;

  /// Default state of the experiment "non-nullable"
  static const bool non_nullable = false;

  /// Default state of the experiment "set-literals"
  static const bool set_literals = true;

  /// Default state of the experiment "spread-collections"
  static const bool spread_collections = true;

  /// Default state of the experiment "triple-shift"
  static const bool triple_shift = false;

  /// Default state of the experiment "bogus-disabled"
  static const bool bogus_disabled = false;

  /// Default state of the experiment "bogus-enabled"
  static const bool bogus_enabled = true;
}

/// Constant bools indicating whether each experimental flag is currently
/// expired (meaning its enable/disable status can no longer be altered from the
/// value in [IsEnabledByDefault]).
class IsExpired {
  /// Expiration status of the experiment "constant-update"
  static const bool constant_update_2018 = false;

  /// Expiration status of the experiment "control-flow-collections"
  static const bool control_flow_collections = true;

  /// Expiration status of the experiment "extension-methods"
  static const bool extension_methods = false;

  /// Expiration status of the experiment "non-nullable"
  static const bool non_nullable = false;

  /// Expiration status of the experiment "set-literals"
  static const bool set_literals = true;

  /// Expiration status of the experiment "spread-collections"
  static const bool spread_collections = true;

  /// Expiration status of the experiment "triple-shift"
  static const bool triple_shift = false;

  /// Expiration status of the experiment "bogus-disabled"
  static const bool bogus_disabled = true;

  /// Expiration status of the experiment "bogus-enabled"
  static const bool bogus_enabled = true;
}
