// Copyright (c) 2019, 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' show File;

import 'package:_fe_analyzer_shared/src/scanner/characters.dart'
    show $A, $MINUS, $a, $z;

import 'package:_fe_analyzer_shared/src/sdk/allowed_experiments.dart';

import 'package:dart_style/dart_style.dart' show DartFormatter;

import 'package:yaml/yaml.dart' show YamlMap, loadYaml;

import '../../test/utils/io_utils.dart' show computeRepoDirUri;

void main(List<String> arguments) {
  final Uri repoDir = computeRepoDirUri();
  new File.fromUri(computeCfeGeneratedFile(repoDir))
      .writeAsStringSync(generateCfeFile(repoDir), flush: true);
  new File.fromUri(computeKernelGeneratedFile(repoDir))
      .writeAsStringSync(generateKernelFile(repoDir), flush: true);
}

Uri computeCfeGeneratedFile(Uri repoDir) {
  return repoDir.resolve(
      "pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart");
}

Uri computeKernelGeneratedFile(Uri repoDir) {
  return repoDir.resolve("pkg/kernel/lib/default_language_version.dart");
}

Uri computeYamlFile(Uri repoDir) {
  return repoDir.resolve("tools/experimental_features.yaml");
}

Uri computeAllowListFile(Uri repoDir) {
  return repoDir.resolve("sdk/lib/_internal/allowed_experiments.json");
}

String generateKernelFile(Uri repoDir) {
  Uri yamlFile = computeYamlFile(repoDir);
  Map<dynamic, dynamic> yaml =
      loadYaml(new File.fromUri(yamlFile).readAsStringSync());

  int currentVersionMajor;
  int currentVersionMinor;
  {
    String currentVersion = getAsVersionNumberString(yaml['current-version'])!;
    List<String> split = currentVersion.split(".");
    currentVersionMajor = int.parse(split[0]);
    currentVersionMinor = int.parse(split[1]);
  }

  StringBuffer sb = new StringBuffer();

  sb.write('''
// Copyright (c) 2021, 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.

// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'tools/experimental_features.yaml' and run
// 'dart pkg/front_end/tool/fasta.dart generate-experimental-flags' to update.

import "ast.dart";

Version defaultLanguageVersion = const Version($currentVersionMajor, $currentVersionMinor);
''');

  return new DartFormatter().format("$sb");
}

String generateCfeFile(Uri repoDir) {
  Uri yamlFile = computeYamlFile(repoDir);
  Map<dynamic, dynamic> yaml =
      loadYaml(new File.fromUri(yamlFile).readAsStringSync());

  int currentVersionMajor;
  int currentVersionMinor;
  {
    String currentVersion = getAsVersionNumberString(yaml['current-version'])!;
    List<String> split = currentVersion.split(".");
    currentVersionMajor = int.parse(split[0]);
    currentVersionMinor = int.parse(split[1]);
  }

  StringBuffer sb = new StringBuffer();

  sb.write('''
// Copyright (c) 2021, 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.

// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'tools/experimental_features.yaml' and run
// 'dart pkg/front_end/tool/fasta.dart generate-experimental-flags' to update.

part of 'experimental_flags.dart';
''');

  Map<String, dynamic> features = {};
  Map<dynamic, dynamic> yamlFeatures = yaml['features'];
  for (MapEntry<dynamic, dynamic> entry in yamlFeatures.entries) {
    String category = entry.value["category"] ?? "language";
    if (category != "language" && category != "CFE") {
      // Skip a feature with a category that's not language or CFE.
      // In the future we might want to generate different code for different
      // things.
      continue;
    }
    features[entry.key] = entry.value;
  }

  List<String> keys = features.keys.toList()..sort();

  sb.write('''

/// An experiment flag including its fixed properties.
class ExperimentalFlag {
  /// The name of this flag as used in the --enable-experiment option.
  final String name;

  /// `true` if this experimental feature is enabled by default.
  ///
  /// When `true`, the feature can still be disabled in individual libraries
  /// with a language version below the [experimentEnabledVersion], and if not
  /// [isExpired], the feature can also be disabled by using a 'no-' prefix
  /// in the --enable-experiment option.
  final bool isEnabledByDefault;

  /// `true` if this feature can no longer be changed using the
  /// --enable-experiment option.
  ///
  /// Libraries can still opt out of the feature by using a language version
  /// below the [experimentEnabledVersion].
  final bool isExpired;
  final Version enabledVersion;

  /// The minimum version that supports this feature.
  ///
  /// If the feature is not enabled by default, this is the current language
  /// version.
  final Version experimentEnabledVersion;

  /// The minimum version that supports this feature in allowed libraries.
  ///
  /// Allowed libraries are specified in
  /// 
  ///    sdk/lib/_internal/allowed_experiments.json
  final Version experimentReleasedVersion;

  const ExperimentalFlag(
      {required this.name,
      required this.isEnabledByDefault,
      required this.isExpired,
      required this.enabledVersion,
      required this.experimentEnabledVersion,
      required this.experimentReleasedVersion});
''');
  for (String key in keys) {
    String identifier = keyToIdentifier(key);
    int enabledInMajor;
    int enabledInMinor;
    String? enabledIn =
        getAsVersionNumberString((features[key] as YamlMap)['enabledIn']);
    if (enabledIn == null) {
      enabledInMajor = currentVersionMajor;
      enabledInMinor = currentVersionMinor;
    } else {
      List<String> split = enabledIn.split(".");
      enabledInMajor = int.parse(split[0]);
      enabledInMinor = int.parse(split[1]);
    }
    bool? expired = (features[key] as YamlMap)['expired'];
    bool shipped = (features[key] as YamlMap)['enabledIn'] != null;
    if (shipped) {
      if (expired == false) {
        throw 'Cannot mark shipped feature "$key" as "expired: false"';
      }
    }
    int releaseMajor;
    int releaseMinor;
    String? experimentalReleaseVersion = getAsVersionNumberString(
        (features[key] as YamlMap)['experimentalReleaseVersion']);
    if (experimentalReleaseVersion != null) {
      List<String> split = experimentalReleaseVersion.split(".");
      releaseMajor = int.parse(split[0]);
      releaseMinor = int.parse(split[1]);
    } else if (enabledIn != null) {
      List<String> split = enabledIn.split(".");
      releaseMajor = int.parse(split[0]);
      releaseMinor = int.parse(split[1]);
    } else {
      releaseMajor = currentVersionMajor;
      releaseMinor = currentVersionMinor;
    }

    sb.writeln('''
  static const ExperimentalFlag ${identifier} =
    const ExperimentalFlag(
      name: '$key',
      isEnabledByDefault: $shipped,
      isExpired: ${expired == true},
      enabledVersion: const Version($enabledInMajor, $enabledInMinor),
      experimentEnabledVersion: const Version($enabledInMajor, $enabledInMinor),
      experimentReleasedVersion: const Version($releaseMajor, $releaseMinor));
''');
  }
  sb.write('''
}
''');

  sb.write('''
/// Interface for accessing the global state of experimental features. 
class GlobalFeatures {
  final Map<ExperimentalFlag, bool> explicitExperimentalFlags;
  final AllowedExperimentalFlags? allowedExperimentalFlags;
  final Map<ExperimentalFlag, bool>? defaultExperimentFlagsForTesting;
  final Map<ExperimentalFlag, Version>? experimentEnabledVersionForTesting;
  final Map<ExperimentalFlag, Version>? experimentReleasedVersionForTesting;

  GlobalFeatures(this.explicitExperimentalFlags,
      {this.allowedExperimentalFlags,
      this.defaultExperimentFlagsForTesting,
      this.experimentEnabledVersionForTesting,
      this.experimentReleasedVersionForTesting});

  GlobalFeature _computeGlobalFeature(ExperimentalFlag flag) {
    return new GlobalFeature(
        flag,
        isExperimentEnabled(flag,
            defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting,
            explicitExperimentalFlags: explicitExperimentalFlags));
  }

  LibraryFeature _computeLibraryFeature(
      ExperimentalFlag flag, Uri canonicalUri, Version libraryVersion) {
    return new LibraryFeature(
        flag,
        isExperimentEnabledInLibrary(flag, canonicalUri,
            defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting,
            explicitExperimentalFlags: explicitExperimentalFlags,
            allowedExperimentalFlags: allowedExperimentalFlags),
        getExperimentEnabledVersionInLibrary(
            flag, canonicalUri, explicitExperimentalFlags,
            allowedExperimentalFlags: allowedExperimentalFlags,
            defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting,
            experimentEnabledVersionForTesting:
                experimentEnabledVersionForTesting,
            experimentReleasedVersionForTesting:
                experimentReleasedVersionForTesting),
        isExperimentEnabledInLibraryByVersion(
            flag, canonicalUri, libraryVersion,
            defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting,
            explicitExperimentalFlags: explicitExperimentalFlags,
            allowedExperimentalFlags: allowedExperimentalFlags));
  }
''');
  for (String key in keys) {
    String identifier = keyToIdentifier(key);
    sb.write('''

  GlobalFeature? _${identifier};
  GlobalFeature get ${identifier} =>
      _${identifier} ??= _computeGlobalFeature(ExperimentalFlag.${identifier});    
''');
  }
  sb.write('''
}

/// Interface for accessing the state of experimental features within a
/// specific library.
class LibraryFeatures {
  final GlobalFeatures globalFeatures;
  final Uri canonicalUri;
  final Version libraryVersion;

  LibraryFeatures(this.globalFeatures, this.canonicalUri, this.libraryVersion);
''');
  for (String key in keys) {
    String identifier = keyToIdentifier(key);
    sb.write('''

  LibraryFeature? _${identifier};
  LibraryFeature get ${identifier} => _${identifier} ??= globalFeatures
      ._computeLibraryFeature(
          ExperimentalFlag.${identifier},
          canonicalUri,
          libraryVersion);
''');
  }
  sb.write('''
}
''');

  sb.write('''
ExperimentalFlag? parseExperimentalFlag(String flag) {
  switch (flag) {
''');
  for (String key in keys) {
    sb.writeln('    case "$key":');
    sb.writeln('     return ExperimentalFlag.${keyToIdentifier(key)};');
  }
  sb.write('''  }
  return null;
}

final Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
''');
  for (String key in keys) {
    sb.writeln('''
  ExperimentalFlag.${keyToIdentifier(key)}:
      ExperimentalFlag.${keyToIdentifier(key)}.isEnabledByDefault,''');
  }
  sb.write('''
};
''');

  Uri allowListFile = computeAllowListFile(repoDir);
  AllowedExperiments allowedExperiments = parseAllowedExperiments(
      new File.fromUri(allowListFile).readAsStringSync());

  sb.write('''
const AllowedExperimentalFlags defaultAllowedExperimentalFlags =
    const AllowedExperimentalFlags(
''');
  sb.writeln('sdkDefaultExperiments: {');
  for (String sdkDefaultExperiment
      in allowedExperiments.sdkDefaultExperiments) {
    sb.writeln('ExperimentalFlag.${keyToIdentifier(sdkDefaultExperiment)},');
  }
  sb.writeln('},');
  sb.writeln('sdkLibraryExperiments: {');
  allowedExperiments.sdkLibraryExperiments
      .forEach((String library, List<String> experiments) {
    sb.writeln('"$library": {');
    for (String experiment in experiments) {
      sb.writeln('ExperimentalFlag.${keyToIdentifier(experiment)},');
    }
    sb.writeln('},');
  });
  sb.writeln('},');
  sb.writeln('packageExperiments: {');
  allowedExperiments.packageExperiments
      .forEach((String package, List<String> experiments) {
    sb.writeln('"$package": {');
    for (String experiment in experiments) {
      sb.writeln('ExperimentalFlag.${keyToIdentifier(experiment)},');
    }
    sb.writeln('},');
  });
  sb.writeln('});');

  return new DartFormatter().format("$sb");
}

String keyToIdentifier(String key, {bool upperCaseFirst = false}) {
  StringBuffer identifier = StringBuffer();
  bool first = true;
  for (int index = 0; index < key.length; ++index) {
    int code = key.codeUnitAt(index);
    if (code == $MINUS) {
      ++index;
      code = key.codeUnitAt(index);
      if ($a <= code && code <= $z) {
        code = code - $a + $A;
      }
    }
    if (first && upperCaseFirst && $a <= code && code <= $z) {
      code = code - $a + $A;
    }
    first = false;
    identifier.writeCharCode(code);
  }
  return identifier.toString();
}

String? getAsVersionNumberString(dynamic value) {
  if (value == null) return null;
  if (value is String) return value;
  if (value is double) return "$value";
  throw "Unexpected value: $value (${value.runtimeType})";
}
