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

/// A Dart function called on each item added to a repeated list
/// to check its type and range.
const checkItem = '\$checkItem';

/// The Dart member names in a GeneratedMessage subclass for one protobuf field.
class MemberNames {
  /// 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;

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

  MemberNames(this.descriptor, this.index, this.fieldName, this.hasMethodName,
      this.clearMethodName);

  MemberNames.forRepeatedField(this.descriptor, this.index, this.fieldName)
      : hasMethodName = null,
        clearMethodName = null;
}

/// Chooses the Dart name of an extension.
String extensionName(FieldDescriptorProto descriptor) {
  var existingNames = new Set<String>()
    ..addAll(_dartReservedWords)
    ..addAll(GeneratedMessage_reservedNames)
    ..addAll(_generatedMessageNames);
  return _unusedMemberNames(descriptor, null, existingNames).fieldName;
}

/// Chooses the name of the Dart class holding top-level extensions.
String extensionClassName(FileDescriptorProto descriptor) {
  var taken = new Set<String>();
  for (var messageType in descriptor.messageType) {
    taken.add(messageOrEnumClassName(messageType.name));
  }
  for (var enumType in descriptor.enumType) {
    taken.add(enumType.name);
  }

  String s = _fileNameWithoutExtension(descriptor).replaceAll('-', '_');
  String candidate = '${s[0].toUpperCase()}${s.substring(1)}';

  if (!taken.contains(candidate)) {
    return candidate;
  }

  // Found a conflict; try again.
  candidate = "${candidate}Ext";
  if (!taken.contains(candidate)) {
    return candidate;
  }

  // Next, try numbers.
  int suffix = 2;
  while (taken.contains("$candidate$suffix")) {
    suffix++;
  }
  return "$candidate$suffix";
}

String _fileNameWithoutExtension(FileDescriptorProto descriptor) {
  Uri path = new Uri.file(descriptor.name);
  String fileName = path.pathSegments.last;
  int 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);
  String toString() => "$message";
}

/// 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, {String parent = ''}) {
  var name = descriptorName;
  if (parent != '') {
    name = '${parent}_${descriptorName}';
  }
  if (name == 'Function') {
    name = 'Function_'; // Avoid reserved word.
  } else if (name == 'List') {
    name = 'List_';
  } else if (name.startsWith('Function_')) {
    // Avoid any further name conflicts due to 'Function' rename (unlikely).
    name = name + '_';
  }
  return name;
}

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

/// Chooses the ProtobufEnum names for each value.
///
/// Since the values all have the same type as the containing enum class, it
/// does not require all the same checks as for message member names. Still,
/// it needs to be checked against a list of reserved names to avoid collisions.
String unusedEnumNames(String name, Set<String> existingNames) {
  final suffix = '_';
  while (existingNames.contains(name)) {
    name += suffix;
  }
  existingNames.add(name);
  return name;
}

/// Chooses the GeneratedMessage member names for each field.
///
/// Additional names to avoid can be supplied using [reserved].
/// (This should only be used for mixins.)
///
/// Returns a map from the field name in the .proto file to its
/// corresponding MemberNames.
///
/// Throws [DartNameOptionException] if a field has this option and
/// it's set to an invalid name.
Map<String, MemberNames> messageFieldNames(DescriptorProto descriptor,
    {Iterable<String> reserved = const []}) {
  var sorted = new List<FieldDescriptorProto>.from(descriptor.field)
    ..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 = new Set<String>()
    ..addAll(_dartReservedWords)
    ..addAll(GeneratedMessage_reservedNames)
    ..addAll(_generatedMessageNames)
    ..addAll(reserved);

  var memberNames = <String, MemberNames>{};

  void takeNames(MemberNames chosen) {
    memberNames[chosen.descriptor.name] = 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) {
      takeNames(_memberNamesFromOption(
          descriptor, field, indexes[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];
      takeNames(_unusedMemberNames(field, index, existingNames));
    }
  }

  // Return a map with entries in sorted order.
  var result = <String, MemberNames>{};
  for (var field in sorted) {
    result[field.name] = memberNames[field.name];
  }
  return result;
}

/// 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.)
MemberNames _memberNamesFromOption(DescriptorProto message,
    FieldDescriptorProto field, int index, 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 new DartNameOptionException(
          "$where: dart_name option is invalid: '$name' is already used");
    }
  }

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

  if (_isRepeated(field)) {
    return new MemberNames.forRepeatedField(field, index, name);
  }

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

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

  return new MemberNames(field, index, name, hasMethod, clearMethod);
}

MemberNames _unusedMemberNames(
    FieldDescriptorProto field, int index, Set<String> existingNames) {
  var suffix = '_' + field.number.toString();

  if (_isRepeated(field)) {
    var name = _defaultFieldName(field);
    while (existingNames.contains(name)) {
      name += suffix;
    }
    return new MemberNames.forRepeatedField(field, index, name);
  }

  String name = _defaultFieldName(field);
  String hasMethod = _defaultHasMethodName(field);
  String clearMethod = _defaultClearMethodName(field);

  while (existingNames.contains(name) ||
      existingNames.contains(hasMethod) ||
      existingNames.contains(clearMethod)) {
    name += suffix;
    hasMethod += suffix;
    clearMethod += suffix;
  }
  return new MemberNames(field, index, name, hasMethod, clearMethod);
}

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

String _defaultHasMethodName(FieldDescriptorProto field) =>
    'has${_fieldMethodSuffix(field)}';

String _defaultClearMethodName(FieldDescriptorProto field) =>
    'clear${_fieldMethodSuffix(field)}';

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

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

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

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

// List of Dart language reserved words in names which cannot be used in a
// subclass of GeneratedMessage.
const List<String> _dartReservedWords = const [
  'assert',
  'break',
  'case',
  'catch',
  'class',
  'const',
  'continue',
  'default',
  'do',
  'else',
  'enum',
  'extends',
  'false',
  'final',
  'finally',
  'for',
  'if',
  'in',
  '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 = const <String>[
  'create',
  'createRepeated',
  'getDefault',
  'List',
  checkItem
];

// 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 = const <String>[
  'List',
  'valueOf',
  'values',
  checkItem
];
