// Copyright (c) 2014, 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:analysis_server/src/utilities/strings.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer_plugin/src/utilities/string_utilities.dart';

final List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to'];

/// Returns all variants of names by removing leading words one by one.
List<String> getCamelWordCombinations(String name) {
  var result = <String>[];
  var parts = getCamelWords(name);
  for (var i = 0; i < parts.length; i++) {
    var s1 = parts[i].toLowerCase();
    var s2 = parts.skip(i + 1).join();
    var suggestion = '$s1$s2';
    result.add(suggestion);
  }
  return result;
}

/// Returns possible names for a variable with the given expected type and
/// expression assigned.
List<String> getVariableNameSuggestionsForExpression(DartType? expectedType,
    Expression? assignedExpression, Set<String> excluded,
    {bool isMethod = false}) {
  String? prefix;

  if (isMethod) {
    // If we're in a build() method, use 'build' as the name prefix.
    var method = assignedExpression?.thisOrAncestorOfType<MethodDeclaration>();
    if (method != null) {
      var enclosingName = method.name.name;
      if (enclosingName.startsWith('build')) {
        prefix = 'build';
      }
    }
  }

  var res = <String>{};
  // use expression
  if (assignedExpression != null) {
    var nameFromExpression = _getBaseNameFromExpression(assignedExpression);
    if (nameFromExpression != null) {
      if (nameFromExpression.startsWith('_')) {
        nameFromExpression = nameFromExpression.substring(1);
      }
      _addAll(excluded, res, getCamelWordCombinations(nameFromExpression),
          prefix: prefix);
    }
    var nameFromParent = _getBaseNameFromLocationInParent(assignedExpression);
    if (nameFromParent != null) {
      _addAll(excluded, res, getCamelWordCombinations(nameFromParent));
    }
  }
  // use type
  if (expectedType != null && !expectedType.isDynamic) {
    if (expectedType.isDartCoreInt) {
      _addSingleCharacterName(excluded, res, 0x69);
    } else if (expectedType.isDartCoreDouble) {
      _addSingleCharacterName(excluded, res, 0x64);
    } else if (expectedType.isDartCoreString) {
      _addSingleCharacterName(excluded, res, 0x73);
    } else if (expectedType is InterfaceType) {
      var className = expectedType.element.name;
      _addAll(excluded, res, getCamelWordCombinations(className));
    }
  }
  // done
  return List.from(res);
}

/// Returns possible names for a [String] variable with [text] value.
List<String> getVariableNameSuggestionsForText(
    String text, Set<String> excluded) {
  // filter out everything except of letters and white spaces
  {
    var sb = StringBuffer();
    for (var i = 0; i < text.length; i++) {
      var c = text.codeUnitAt(i);
      if (isLetter(c) || isWhitespace(c)) {
        sb.writeCharCode(c);
      }
    }
    text = sb.toString();
  }
  // make single camel-case text
  {
    var words = text.split(' ');
    var sb = StringBuffer();
    for (var i = 0; i < words.length; i++) {
      var word = words[i];
      if (i > 0) {
        // `capitalize` won't return `null` unless `null` is passed in.
        word = capitalize(word)!;
      }
      sb.write(word);
    }
    text = sb.toString();
  }
  // split camel-case into separate suggested names
  var res = <String>{};
  _addAll(excluded, res, getCamelWordCombinations(text));
  return List.from(res);
}

/// Adds [toAdd] items which are not excluded.
void _addAll(Set<String> excluded, Set<String> result, Iterable<String> toAdd,
    {String? prefix}) {
  for (var item in toAdd) {
    // add name based on "item", but not "excluded"
    for (var suffix = 1;; suffix++) {
      // prepare name, just "item" or "item2", "item3", etc
      var name = item;
      if (suffix > 1) {
        name += suffix.toString();
      }
      // add once found not excluded
      if (!excluded.contains(name)) {
        result.add(prefix == null ? name : '$prefix${capitalize(name)}');
        break;
      }
    }
  }
}

/// Adds to [result] either [c] or the first ASCII character after it.
void _addSingleCharacterName(Set<String> excluded, Set<String> result, int c) {
  while (c < 0x7A) {
    var name = String.fromCharCode(c);
    // may be done
    if (!excluded.contains(name)) {
      result.add(name);
      break;
    }
    // next character
    c = c + 1;
  }
}

String? _getBaseNameFromExpression(Expression expression) {
  if (expression is AsExpression) {
    return _getBaseNameFromExpression(expression.expression);
  } else if (expression is ParenthesizedExpression) {
    return _getBaseNameFromExpression(expression.expression);
  }
  return _getBaseNameFromUnwrappedExpression(expression);
}

String? _getBaseNameFromLocationInParent(Expression expression) {
  // value in named expression
  if (expression.parent is NamedExpression) {
    var namedExpression = expression.parent as NamedExpression;
    if (namedExpression.expression == expression) {
      return namedExpression.name.label.name;
    }
  }
  // positional argument
  var parameter = expression.staticParameterElement;
  if (parameter != null) {
    return parameter.displayName;
  }
  // unknown
  return null;
}

String? _getBaseNameFromUnwrappedExpression(Expression expression) {
  String? name;
  // analyze expressions
  if (expression is SimpleIdentifier) {
    return expression.name;
  } else if (expression is PrefixedIdentifier) {
    return expression.identifier.name;
  } else if (expression is PropertyAccess) {
    return expression.propertyName.name;
  } else if (expression is MethodInvocation) {
    name = expression.methodName.name;
  } else if (expression is InstanceCreationExpression) {
    var constructorName = expression.constructorName;
    var namedType = constructorName.type2;
    var typeNameIdentifier = namedType.name;
    // new ClassName()
    if (typeNameIdentifier is SimpleIdentifier) {
      return typeNameIdentifier.name;
    }
    // new prefix.name();
    if (typeNameIdentifier is PrefixedIdentifier) {
      var prefixed = typeNameIdentifier;
      // new prefix.ClassName()
      if (prefixed.prefix.staticElement is PrefixElement) {
        return prefixed.identifier.name;
      }
      // new ClassName.constructorName()
      return prefixed.prefix.name;
    }
  } else if (expression is IndexExpression) {
    name = _getBaseNameFromExpression(expression.realTarget);
    if (name != null && name.endsWith('s')) {
      name = name.substring(0, name.length - 1);
    }
  }
  // strip known prefixes
  if (name != null) {
    for (var i = 0; i < _KNOWN_METHOD_NAME_PREFIXES.length; i++) {
      var curr = _KNOWN_METHOD_NAME_PREFIXES[i];
      if (name.startsWith(curr)) {
        if (name == curr) {
          return null;
        } else if (isUpperCase(name.codeUnitAt(curr.length))) {
          return name.substring(curr.length);
        }
      }
    }
  }
  // done
  return name;
}
