// Copyright (c) 2020, 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:io';

import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:args/args.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:dartdev/src/sdk.dart';

const experimentFlagName = 'enable-experiment';

/// Return a list of all the non-expired Dart experiments.
List<ExperimentalFeature> get experimentalFeatures =>
    ExperimentStatus.knownFeatures.values
        .where((feature) => !feature.isExpired)
        .toList()
      ..sort((a, b) => a.enableString.compareTo(b.enableString));

extension ArgParserExtensions on ArgParser {
  void addExperimentalFlags({bool verbose = false}) {
    List<ExperimentalFeature> features = experimentalFeatures;

    Map<String, String> allowedHelp = {};
    for (ExperimentalFeature feature in features) {
      String suffix =
          feature.isEnabledByDefault ? ' (no-op - enabled by default)' : '';
      allowedHelp[feature.enableString] = '${feature.documentation}$suffix';
    }

    addMultiOption(
      experimentFlagName,
      valueHelp: 'experiment',
      allowedHelp: verbose ? allowedHelp : null,
      help: 'Enable one or more experimental features '
          '(see dart.dev/go/experiments).',
      hide: !verbose,
    );
  }
}

extension ArgResultsExtensions on ArgResults {
  List<String> get enabledExperiments {
    List<String> enabledExperiments = [];
    // Check to see if the ArgParser which generated this result accepts
    // `--enable-experiment` as an option. If so, return the result if it was
    // provided.
    if (options.contains(experimentFlagName)) {
      if (wasParsed(experimentFlagName)) {
        enabledExperiments = multiOption(experimentFlagName);
      }
    } else {
      // In the case where a command uses `ArgParser.allowAnything()` as its
      // parser, the valid set of options for the command isn't specified and
      // isn't enforced. Instead, we have to manually parse the arguments to
      // look for `--enable-experiment=`. Currently, this path is only taken for
      // the `pub` and `test` commands, as well as when we are trying to send
      // analytics.
      final experiments = arguments.firstWhereOrNull(
        (e) => e.startsWith('--$experimentFlagName='),
      );
      if (experiments == null) {
        return [];
      }
      enabledExperiments = experiments.split('=')[1].split(',');
    }

    for (final feature in experimentalFeatures) {
      // We allow default true flags, but complain when they are passed in.
      if (feature.isEnabledByDefault &&
          enabledExperiments.contains(feature.enableString)) {
        stderr.writeln("'${feature.enableString}' is now enabled by default; "
            'this flag is no longer required.');
      }
    }
    return enabledExperiments;
  }
}

List<String> parseVmEnabledExperiments(List<String> vmArgs) {
  var experiments = <String>[];
  var itr = vmArgs.iterator;
  while (itr.moveNext()) {
    var arg = itr.current;
    if (arg == '--$experimentFlagName') {
      if (!itr.moveNext()) break;
      experiments.add(itr.current);
    } else if (arg.startsWith('--$experimentFlagName=')) {
      var parts = arg.split('=');
      if (parts.length == 2) {
        experiments.addAll(parts[1].split(','));
      }
    }
  }
  return experiments;
}

bool nativeAssetsEnabled(List<String> vmEnabledExperiments) =>
    vmEnabledExperiments
        .contains(ExperimentalFeatures.native_assets.enableString) ||
    (_availableOnCurrentChannel(ExperimentalFeatures.native_assets.channels) &&
        ExperimentalFeatures.native_assets.isEnabledByDefault);

bool recordUseEnabled(List<String> vmEnabledExperiments) =>
    vmEnabledExperiments.contains(ExperimentalFeatures.record_use.enableString);

List<String> validateExperiments(List<String> vmEnabledExperiments) {
  final errors = <String>[];
  for (final enabledExperiment in vmEnabledExperiments) {
    final experiment = experimentalFeatures.firstWhereOrNull(
        (feature) => feature.enableString == enabledExperiment);
    if (experiment == null) {
      errors.add('Unknown experiment: $enabledExperiment');
    } else if (!_availableOnCurrentChannel(experiment.channels)) {
      final availableChannels = experiment.channels.join(', ');
      final s = experiment.channels.length >= 2 ? 's' : '';
      errors.add(
        'Unavailable experiment: ${experiment.enableString} (this experiment '
        'is only available on the $availableChannels channel$s, '
        'this current channel is ${Runtime.runtime.channel})',
      );
    }
  }
  return errors;
}

bool _availableOnCurrentChannel(List<String> channels) {
  final channel = Runtime.runtime.channel;
  return channels.contains(channel);
}
