// Copyright (c) 2016, 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 'package:protobuf/meta.dart';
import 'package:protoc_plugin/src/dart_options.pb.dart';
import 'package:protoc_plugin/src/descriptor.pb.dart';

class MemberNames {
  List<FieldNames> fieldNames;
  List<OneofNames> oneofNames;
  MemberNames(this.fieldNames, this.oneofNames);
}

/// The Dart member names in a GeneratedMessage subclass for one protobuf field.
class FieldNames {
  /// The descriptor of the field these member names apply to.
  final FieldDescriptorProto descriptor;

  /// The index of this field in MessageGenerator.fieldList.
  /// The same index will be stored in FieldInfo.index.
  final int index;

  /// The position of this field as it appeared in the original DescriptorProto.
  /// Used to construct metadata.
  final int sourcePosition;

  /// Identifier for generated getters/setters.
  final String fieldName;

  /// Identifier for the generated hasX() method, without braces.
  ///
  /// `null` for repeated fields.
  final String hasMethodName;

  /// Identifier for the generated clearX() method, without braces.
  ///
  /// `null` for repeated fields.
  final String clearMethodName;

  // Identifier for the generated ensureX() method, without braces.
  //
  //'null' for scalar, repeated, and map fields.
  final String ensureMethodName;

  FieldNames(this.descriptor, this.index, this.sourcePosition, this.fieldName,
      {this.hasMethodName, this.clearMethodName, this.ensureMethodName});
}

/// The Dart names associated with a oneof declaration.
class OneofNames {
  final OneofDescriptorProto descriptor;

  /// Index in the containing type's oneof_decl list.
  final int index;

  /// Identifier for the generated whichX() method, without braces.
  final String whichOneofMethodName;

  /// Identifier for the generated clearX() method, without braces.
  final String clearMethodName;

  /// Identifier for the generated enum definition.
  final String oneofEnumName;

  ///  Identifier for the _XByTag map.
  final String byTagMapName;

  OneofNames(this.descriptor, this.index, this.clearMethodName,
      this.whichOneofMethodName, this.oneofEnumName, this.byTagMapName);
}

// For performance reasons, use code units instead of Regex.
bool _startsWithDigit(String input) =>
    input.isNotEmpty && (input.codeUnitAt(0) ^ 0x30) <= 9;

/// Move any initial underscores in [input] to the end.
///
/// According to the spec identifiers cannot start with _, but it seems to be
/// accepted by protoc. These identifiers are private in Dart, so they have to
/// be transformed.
///
/// If [input] starts with a digit after transformation, prefix with an 'x'.
String avoidInitialUnderscore(String input) {
  while (input.startsWith('_')) {
    input = '${input.substring(1)}_';
  }
  if (_startsWithDigit(input)) {
    input = 'x$input';
  }
  return input;
}

/// Returns [input] surrounded by single quotes and with all '$'s escaped.
String singleQuote(String input) {
  return "'${input.replaceAll(r'$', r'\$')}'";
}

/// Chooses the Dart name of an extension.
String extensionName(FieldDescriptorProto descriptor, Set<String> usedNames) {
  return _unusedMemberNames(descriptor, null, null, usedNames).fieldName;
}

Iterable<String> extensionSuffixes() sync* {
  yield "Ext";
  var i = 2;
  while (true) {
    yield '$i';
    i++;
  }
}

/// Replaces all characters in [imput] that are not valid in a dart identifier
/// with _.
///
/// This function does not take care of leading underscores.
String legalDartIdentifier(String imput) {
  return imput.replaceAll(RegExp(r'[^a-zA-Z0-9$_]'), '_');
}

/// Chooses the name of the Dart class holding top-level extensions.
String extensionClassName(
    FileDescriptorProto descriptor, Set<String> usedNames) {
  var s = avoidInitialUnderscore(
      legalDartIdentifier(_fileNameWithoutExtension(descriptor)));
  var candidate = '${s[0].toUpperCase()}${s.substring(1)}';
  return disambiguateName(candidate, usedNames, extensionSuffixes());
}

String _fileNameWithoutExtension(FileDescriptorProto descriptor) {
  var path = Uri.file(descriptor.name);
  var fileName = path.pathSegments.last;
  var dot = fileName.lastIndexOf(".");
  return dot == -1 ? fileName : fileName.substring(0, dot);
}

// Exception thrown when a field has an invalid 'dart_name' option.
class DartNameOptionException implements Exception {
  final String message;
  DartNameOptionException(this.message);
  @override
  String toString() => "$message";
}

/// Returns a [name] that is not contained in [usedNames] by suffixing it with
/// the first possible suffix from [suffixes].
///
/// The chosen name is added to [usedNames].
///
/// If [variants] is given, all the variants of a name must be available before
/// that name is chosen, and all the chosen variants will be added to
/// [usedNames].
/// The returned name is that, which will generate the accepted variants.
String disambiguateName(
    String name, Set<String> usedNames, Iterable<String> suffixes,
    {List<String> Function(String candidate) generateVariants}) {
  generateVariants ??= (String name) => <String>[name];

  bool allVariantsAvailable(List<String> variants) {
    return variants.every((String variant) => !usedNames.contains(variant));
  }

  var usedSuffix = '';
  var candidateVariants = generateVariants(name);

  if (!allVariantsAvailable(candidateVariants)) {
    for (var suffix in suffixes) {
      candidateVariants = generateVariants('$name$suffix');
      if (allVariantsAvailable(candidateVariants)) {
        usedSuffix = suffix;
        break;
      }
    }
  }

  usedNames.addAll(candidateVariants);
  return '$name$usedSuffix';
}

Iterable<String> defaultSuffixes() sync* {
  yield '_';
  var i = 0;
  while (true) {
    yield ('_$i');
    i++;
  }
}

String oneofEnumClassName(
    String descriptorName, Set<String> usedNames, String parentName) {
  descriptorName = '${parentName}_${underscoresToCamelCase(descriptorName)}';
  return disambiguateName(
      avoidInitialUnderscore(descriptorName), usedNames, defaultSuffixes());
}

String oneofEnumMemberName(String fieldName) => disambiguateName(
    fieldName, Set<String>.from(_oneofEnumMemberNames), defaultSuffixes());

/// Chooses the name of the Dart class to generate for a proto message or enum.
///
/// For a nested message or enum, [parent] should be provided
/// with the name of the Dart class for the immediate parent.
String messageOrEnumClassName(String descriptorName, Set<String> usedNames,
    {String parent = ''}) {
  if (parent != '') {
    descriptorName = '${parent}_${descriptorName}';
  }
  return disambiguateName(
      avoidInitialUnderscore(descriptorName), usedNames, defaultSuffixes());
}

/// Returns the set of names reserved by the ProtobufEnum class and its
/// generated subclasses.
Set<String> get reservedEnumNames => <String>{}
  ..addAll(ProtobufEnum_reservedNames)
  ..addAll(_dartReservedWords)
  ..addAll(_protobufEnumNames);

Iterable<String> enumSuffixes() sync* {
  var s = '_';
  while (true) {
    yield s;
    s += '_';
  }
}

/// Chooses the GeneratedMessage member names for each field and names
/// associated with each oneof declaration.
///
/// Additional names to avoid can be supplied using [reserved].
/// (This should only be used for mixins.)
///
/// Returns [MemberNames] which holds a list with [FieldNames] and a list with [OneofNames].
///
/// Throws [DartNameOptionException] if a field has this option and
/// it's set to an invalid name.
MemberNames messageMemberNames(DescriptorProto descriptor,
    String parentClassName, Set<String> usedTopLevelNames,
    {Iterable<String> reserved = const []}) {
  var fieldList = List<FieldDescriptorProto>.from(descriptor.field);
  var sourcePositions =
      fieldList.asMap().map((index, field) => MapEntry(field.name, index));
  var sorted = fieldList
    ..sort((FieldDescriptorProto a, FieldDescriptorProto b) {
      if (a.number < b.number) return -1;
      if (a.number > b.number) return 1;
      throw "multiple fields defined for tag ${a.number} in ${descriptor.name}";
    });

  // Choose indexes first, based on their position in the sorted list.
  var indexes = <String, int>{};
  for (var field in sorted) {
    var index = indexes.length;
    indexes[field.name] = index;
  }

  var existingNames = <String>{}..addAll(reservedMemberNames)..addAll(reserved);

  var fieldNames = List<FieldNames>(indexes.length);

  void takeFieldNames(FieldNames chosen) {
    fieldNames[chosen.index] = chosen;

    existingNames.add(chosen.fieldName);
    if (chosen.hasMethodName != null) {
      existingNames.add(chosen.hasMethodName);
    }
    if (chosen.clearMethodName != null) {
      existingNames.add(chosen.clearMethodName);
    }
  }

  // Handle fields with a dart_name option.
  // They have higher priority than automatically chosen names.
  // Explicitly setting a name that's already taken is a build error.
  for (var field in sorted) {
    if (_nameOption(field).isNotEmpty) {
      takeFieldNames(_memberNamesFromOption(descriptor, field,
          indexes[field.name], sourcePositions[field.name], existingNames));
    }
  }

  // Then do other fields.
  // They are automatically renamed until we find something unused.
  for (var field in sorted) {
    if (_nameOption(field).isEmpty) {
      var index = indexes[field.name];
      var sourcePosition = sourcePositions[field.name];
      takeFieldNames(
          _unusedMemberNames(field, index, sourcePosition, existingNames));
    }
  }

  var oneofNames = <OneofNames>[];

  void takeOneofNames(OneofNames chosen) {
    oneofNames.add(chosen);

    if (chosen.whichOneofMethodName != null) {
      existingNames.add(chosen.whichOneofMethodName);
    }
    if (chosen.clearMethodName != null) {
      existingNames.add(chosen.clearMethodName);
    }
    if (chosen.byTagMapName != null) {
      existingNames.add(chosen.byTagMapName);
    }
  }

  List<String> oneofNameVariants(String name) {
    return [_defaultWhichMethodName(name), _defaultClearMethodName(name)];
  }

  for (var i = 0; i < descriptor.oneofDecl.length; i++) {
    var oneof = descriptor.oneofDecl[i];

    var oneofName = disambiguateName(
        underscoresToCamelCase(oneof.name), existingNames, defaultSuffixes(),
        generateVariants: oneofNameVariants);

    var oneofEnumName =
        oneofEnumClassName(oneof.name, usedTopLevelNames, parentClassName);

    var enumMapName = disambiguateName(
        '_${oneofEnumName}ByTag', existingNames, defaultSuffixes());

    takeOneofNames(OneofNames(oneof, i, _defaultClearMethodName(oneofName),
        _defaultWhichMethodName(oneofName), oneofEnumName, enumMapName));
  }

  return MemberNames(fieldNames, oneofNames);
}

/// Chooses the member names for a field that has the 'dart_name' option.
///
/// If the explicitly-set Dart name is already taken, throw an exception.
/// (Fails the build.)
FieldNames _memberNamesFromOption(
    DescriptorProto message,
    FieldDescriptorProto field,
    int index,
    int sourcePosition,
    Set<String> existingNames) {
  // TODO(skybrian): provide more context in errors (filename).
  var where = "${message.name}.${field.name}";

  void checkAvailable(String name) {
    if (existingNames.contains(name)) {
      throw DartNameOptionException(
          "$where: dart_name option is invalid: '$name' is already used");
    }
  }

  var name = _nameOption(field);
  if (name.isEmpty) {
    throw ArgumentError("field doesn't have dart_name option");
  }
  if (!_isDartFieldName(name)) {
    throw DartNameOptionException("$where: dart_name option is invalid: "
        "'$name' is not a valid Dart field name");
  }
  checkAvailable(name);

  if (_isRepeated(field)) {
    return FieldNames(field, index, sourcePosition, name);
  }

  var hasMethod = "has${_capitalize(name)}";
  checkAvailable(hasMethod);

  var clearMethod = "clear${_capitalize(name)}";
  checkAvailable(clearMethod);

  String ensureMethod;

  if (_isGroupOrMessage(field)) {
    ensureMethod = 'ensure${_capitalize(name)}';
    checkAvailable(ensureMethod);
  }
  return FieldNames(field, index, sourcePosition, name,
      hasMethodName: hasMethod,
      clearMethodName: clearMethod,
      ensureMethodName: ensureMethod);
}

Iterable<String> _memberNamesSuffix(int number) sync* {
  var suffix = '_$number';
  while (true) {
    yield suffix;
    suffix = '${suffix}_$number';
  }
}

FieldNames _unusedMemberNames(FieldDescriptorProto field, int index,
    int sourcePosition, Set<String> existingNames) {
  if (_isRepeated(field)) {
    return FieldNames(
        field,
        index,
        sourcePosition,
        disambiguateName(_defaultFieldName(_fieldMethodSuffix(field)),
            existingNames, _memberNamesSuffix(field.number)));
  }

  List<String> generateNameVariants(String name) {
    var result = <String>[
      _defaultFieldName(name),
      _defaultHasMethodName(name),
      _defaultClearMethodName(name),
    ];

    // TODO(zarah): Use 'collection if' when sdk dependency is updated.
    if (_isGroupOrMessage(field)) result.add(_defaultEnsureMethodName(name));

    return result;
  }

  var name = disambiguateName(_fieldMethodSuffix(field), existingNames,
      _memberNamesSuffix(field.number),
      generateVariants: generateNameVariants);

  return FieldNames(field, index, sourcePosition, _defaultFieldName(name),
      hasMethodName: _defaultHasMethodName(name),
      clearMethodName: _defaultClearMethodName(name),
      ensureMethodName:
          _isGroupOrMessage(field) ? _defaultEnsureMethodName(name) : null);
}

/// The name to use by default for the Dart getter and setter.
/// (A suffix will be added if there is a conflict.)
String _defaultFieldName(String fieldMethodSuffix) {
  return '${fieldMethodSuffix[0].toLowerCase()}${fieldMethodSuffix.substring(1)}';
}

String _defaultHasMethodName(String fieldMethodSuffix) =>
    'has$fieldMethodSuffix';

String _defaultClearMethodName(String fieldMethodSuffix) =>
    'clear$fieldMethodSuffix';

String _defaultWhichMethodName(String oneofMethodSuffix) =>
    'which$oneofMethodSuffix';

String _defaultEnsureMethodName(String fieldMethodSuffix) =>
    'ensure$fieldMethodSuffix';

/// The suffix to use for this field in Dart method names.
/// (It should be camelcase and begin with an uppercase letter.)
String _fieldMethodSuffix(FieldDescriptorProto field) {
  var name = _nameOption(field);
  if (name.isNotEmpty) return _capitalize(name);

  if (field.type != FieldDescriptorProto_Type.TYPE_GROUP) {
    return underscoresToCamelCase(field.name);
  }

  // For groups, use capitalization of 'typeName' rather than 'name'.
  name = field.typeName;
  var index = name.lastIndexOf('.');
  if (index != -1) {
    name = name.substring(index + 1);
  }
  return underscoresToCamelCase(name);
}

String underscoresToCamelCase(s) => s.split('_').map(_capitalize).join('');

String _capitalize(s) =>
    s.isEmpty ? s : '${s[0].toUpperCase()}${s.substring(1)}';

bool _isRepeated(FieldDescriptorProto field) =>
    field.label == FieldDescriptorProto_Label.LABEL_REPEATED;

bool _isGroupOrMessage(FieldDescriptorProto field) =>
    field.type == FieldDescriptorProto_Type.TYPE_MESSAGE ||
    field.type == FieldDescriptorProto_Type.TYPE_GROUP;

String _nameOption(FieldDescriptorProto field) =>
    field.options.getExtension(Dart_options.dartName);

bool _isDartFieldName(name) => name.startsWith(_dartFieldNameExpr);

final _dartFieldNameExpr = RegExp(r'^[a-z]\w+$');

/// Names that would collide as top-level identifiers.
final List<String> forbiddenTopLevelNames = <String>[
  'List',
  'Function',
  'Map',
  ..._dartReservedWords,
];

final List<String> reservedMemberNames = <String>[
  ..._dartReservedWords,
  ...GeneratedMessage_reservedNames,
  ..._generatedMessageNames
];

final List<String> forbiddenExtensionNames = <String>[
  ..._dartReservedWords,
  ...GeneratedMessage_reservedNames,
  ..._generatedMessageNames
];

// List of Dart language reserved words in names which cannot be used in a
// subclass of GeneratedMessage.
const List<String> _dartReservedWords = [
  'assert',
  'bool',
  'break',
  'case',
  'catch',
  'class',
  'const',
  'continue',
  'default',
  'do',
  'double',
  'else',
  'enum',
  'extends',
  'false',
  'final',
  'finally',
  'for',
  'if',
  'in',
  'int',
  'is',
  'new',
  'null',
  'rethrow',
  'return',
  'super',
  'switch',
  'this',
  'throw',
  'true',
  'try',
  'var',
  'void',
  'while',
  'with'
];

// List of names used in the generated message classes.
//
// This is in addition to GeneratedMessage_reservedNames, which are names from
// the base GeneratedMessage class determined by reflection.
const _generatedMessageNames = <String>[
  'create',
  'createRepeated',
  'getDefault',
  'List',
  'notSet'
];

// List of names used in the generated enum classes.
//
// This is in addition to ProtobufEnum_reservedNames, which are names from the
// base ProtobufEnum class determined by reflection.
const _protobufEnumNames = <String>[
  'List',
  'valueOf',
  'values',
];

// List of names used in Dart enums, which can't be used as enum member names.
const _oneofEnumMemberNames = <String>['default', 'index', 'values'];
