// 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 https://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);

bool dataAssetsEnabled(List<String> vmEnabledExperiments) =>
    vmEnabledExperiments.contains(
      ExperimentalFeatures.data_assets.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);
}
