// 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;

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('''

enum ExperimentalFlag {
''');
  for (String key in keys) {
    sb.writeln('  ${keyToIdentifier(key)},');
  }
  sb.write('''
}

''');

  for (String key in keys) {
    int major;
    int minor;
    String? enabledIn =
        getAsVersionNumberString((features[key] as YamlMap)['enabledIn']);
    if (enabledIn == null) {
      major = currentVersionMajor;
      minor = currentVersionMinor;
    } else {
      List<String> split = enabledIn.split(".");
      major = int.parse(split[0]);
      minor = int.parse(split[1]);
    }
    sb.writeln('  const Version enable'
        '${keyToIdentifier(key, upperCaseFirst: true)}'
        'Version = const Version($major, $minor);');
  }

  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;
}

const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
''');
  for (String key in keys) {
    bool expired = (features[key] as YamlMap)['expired'];
    bool shipped = (features[key] as YamlMap)['enabledIn'] != null;
    sb.writeln('  ExperimentalFlag.${keyToIdentifier(key)}: ${shipped},');
    if (shipped) {
      if (expired == false) {
        throw 'Cannot mark shipped feature as "expired: false"';
      }
    }
  }
  sb.write('''
};

const Map<ExperimentalFlag, bool> expiredExperimentalFlags = {
''');
  for (String key in keys) {
    bool expired = (features[key] as YamlMap)['expired'] == true;
    sb.writeln('  ExperimentalFlag.${keyToIdentifier(key)}: ${expired},');
  }
  sb.write('''
};

const Map<ExperimentalFlag, Version> experimentEnabledVersion = {
''');
  for (String key in keys) {
    int major;
    int minor;
    String? enabledIn =
        getAsVersionNumberString((features[key] as YamlMap)['enabledIn']);
    if (enabledIn != null) {
      List<String> split = enabledIn.split(".");
      major = int.parse(split[0]);
      minor = int.parse(split[1]);
    } else {
      major = currentVersionMajor;
      minor = currentVersionMinor;
    }
    sb.writeln('  ExperimentalFlag.${keyToIdentifier(key)}: '
        'const Version($major, $minor),');
  }
  sb.write('''
};

const Map<ExperimentalFlag, Version> experimentReleasedVersion = {
''');
  for (String key in keys) {
    int major;
    int minor;
    String? enabledIn =
        getAsVersionNumberString((features[key] as YamlMap)['enabledIn']);
    String? experimentalReleaseVersion = getAsVersionNumberString(
        (features[key] as YamlMap)['experimentalReleaseVersion']);
    if (experimentalReleaseVersion != null) {
      List<String> split = experimentalReleaseVersion.split(".");
      major = int.parse(split[0]);
      minor = int.parse(split[1]);
    } else if (enabledIn != null) {
      List<String> split = enabledIn.split(".");
      major = int.parse(split[0]);
      minor = int.parse(split[1]);
    } else {
      major = currentVersionMajor;
      minor = currentVersionMinor;
    }
    sb.writeln('  ExperimentalFlag.${keyToIdentifier(key)}: '
        'const Version($major, $minor),');
  }
  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");
}

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})";
}
