/// This file contains code to generate experimental flags
/// based on the information in tools/experimental_features.yaml.
import 'dart:io';

import 'package:_fe_analyzer_shared/src/scanner/characters.dart'
    show $MINUS, $_;
import 'package:analysis_tool/package_root.dart' as pkg_root;
import 'package:analysis_tool/tools.dart';
import 'package:path/path.dart';
import 'package:yaml/yaml.dart' show YamlMap, loadYaml;

main() async {
  await GeneratedContent.generateAll(
      normalize(join(pkg_root.packageRoot, 'analyzer')), allTargets);
}

List<GeneratedContent> get allTargets {
  Map<dynamic, dynamic> experimentsYaml = loadYaml(File(join(
          normalize(join(pkg_root.packageRoot, '../tools')),
          'experimental_features.yaml'))
      .readAsStringSync());

  return <GeneratedContent>[
    GeneratedFile('lib/src/dart/analysis/experiments.g.dart',
        (String pkgPath) async {
      var generator = _ExperimentsGenerator(experimentsYaml);
      generator.generateFormatCode();
      return generator.out.toString();
    }),
  ];
}

String keyToIdentifier(String key) {
  var identifier = StringBuffer();
  for (int index = 0; index < key.length; ++index) {
    var code = key.codeUnitAt(index);
    if (code == $MINUS) {
      code = $_;
    }
    identifier.writeCharCode(code);
  }
  return identifier.toString();
}

class _ExperimentsGenerator {
  final Map experimentsYaml;

  List<String> keysSorted;

  final out = StringBuffer('''
//
// THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'tools/experimental_features.yaml' and run
// 'dart pkg/analyzer/tool/experiments/generate.dart' to update.

part of 'experiments.dart';
''');

  Map<String, dynamic> _features;

  _ExperimentsGenerator(this.experimentsYaml);

  Map<String, dynamic> get features {
    if (_features != null) return _features;
    _features = {};
    Map yamlFeatures = experimentsYaml['features'];
    for (MapEntry entry in yamlFeatures.entries) {
      String category = entry.value['category'] ?? 'language';
      if (category != "language") {
        // Skip a feature with a category that's not language. In the future
        // possibly allow e.g. 'analyzer' etc.
        continue;
      }
      _features[entry.key] = entry.value;
    }

    return _features;
  }

  void generateFormatCode() {
    keysSorted = features.keys.toList()..sort();
    generateSection_CurrentVersion();
    generateSection_KnownFeatures();
    generateSection_EnableString();
    generateSection_ExperimentalFeature();
    generateSection_IsEnabledByDefault();
    generateSection_IsExpired();
    generateSection_CurrentState();
  }

  void generateSection_CurrentState() {
    out.write('''

mixin _CurrentState {
''');
    for (var key in keysSorted) {
      var id = keyToIdentifier(key);
      out.write('''
  /// Current state for the flag "$key"
  bool get $id => isEnabled(ExperimentalFeatures.$id);
    ''');
    }
    out.write('''

  bool isEnabled(covariant ExperimentalFeature feature);
}''');
  }

  void generateSection_CurrentVersion() {
    var version = _versionNumberAsString(experimentsYaml['current-version']);
    out.write('''

/// The current version of the Dart language (or, for non-stable releases, the
/// version of the language currently in the process of being developed).
const _currentVersion = '$version';
    ''');
  }

  void generateSection_EnableString() {
    out.write('''

/// Constant strings for enabling each of the currently known experimental
/// flags.
class EnableString {
''');
    for (var key in keysSorted) {
      out.write('''
      /// String to enable the experiment "$key"
      static const String ${keyToIdentifier(key)} = '$key';
    ''');
    }
    out.write('''
    }''');
  }

  void generateSection_ExperimentalFeature() {
    out.write('''

class ExperimentalFeatures {
''');
    int index = 0;
    for (var key in keysSorted) {
      var id = keyToIdentifier(key);
      var help = (features[key] as YamlMap)['help'] ?? '';
      var experimentalReleaseVersion =
          (features[key] as YamlMap)['experimentalReleaseVersion'];
      var enabledIn = (features[key] as YamlMap)['enabledIn'];
      out.write('''

      static final $id = ExperimentalFeature(
        index: $index,
        enableString: EnableString.$id,
        isEnabledByDefault: IsEnabledByDefault.$id,
        isExpired: IsExpired.$id,
        documentation: '$help',
    ''');

      if (experimentalReleaseVersion != null) {
        experimentalReleaseVersion =
            _versionNumberAsString(experimentalReleaseVersion);
        out.write("experimentalReleaseVersion: ");
        out.write("Version.parse('$experimentalReleaseVersion'),");
      } else {
        out.write("experimentalReleaseVersion: null,");
      }

      if (enabledIn != null) {
        enabledIn = _versionNumberAsString(enabledIn);
        out.write("releaseVersion: Version.parse('$enabledIn'),");
      } else {
        out.write("releaseVersion: null,");
      }
      out.writeln(');');
      ++index;
    }
    out.write('''
    }''');
  }

  void generateSection_IsEnabledByDefault() {
    out.write('''

/// Constant bools indicating whether each experimental flag is currently
/// enabled by default.
class IsEnabledByDefault {
''');
    for (var key in keysSorted) {
      var entry = features[key] as YamlMap;
      bool shipped = entry['enabledIn'] != null;
      out.write('''
      /// Default state of the experiment "$key"
      static const bool ${keyToIdentifier(key)} = $shipped;
    ''');
    }
    out.write('''
    }''');
  }

  void generateSection_IsExpired() {
    out.write('''

/// 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 {
''');
    for (var key in keysSorted) {
      var entry = features[key] as YamlMap;
      bool shipped = entry['enabledIn'] != null;
      bool expired = entry['expired'];
      out.write('''
      /// Expiration status of the experiment "$key"
      static const bool ${keyToIdentifier(key)} = ${expired == true};
    ''');
      if (shipped && expired == false) {
        throw 'Cannot mark shipped feature as "expired: false"';
      }
    }
    out.write('''
    }''');
  }

  void generateSection_KnownFeatures() {
    out.write('''

/// A map containing information about all known experimental flags.
final _knownFeatures = <String, ExperimentalFeature>{
''');
    for (var key in keysSorted) {
      var id = keyToIdentifier(key);
      out.write('''
  EnableString.$id: ExperimentalFeatures.$id,
    ''');
    }
    out.write('''
};
''');
  }

  String _versionNumberAsString(dynamic enabledIn) {
    if (enabledIn is double) {
      return '$enabledIn.0';
    } else {
      return enabledIn.toString();
    }
  }
}
