// Copyright (c) 2015, 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/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analysis_server/src/utilities/extensions/completion_request.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';

/// A contributor that produces suggestions based on the static members of a
/// given class, enum, or extension. More concretely, this class produces
/// suggestions for expressions of the form `C.^`, where `C` is the name of a
/// class, enum, or extension.
class StaticMemberContributor extends DartCompletionContributor {
  StaticMemberContributor(
    DartCompletionRequest request,
    SuggestionBuilder builder,
  ) : super(request, builder);

  @override
  Future<void> computeSuggestions() async {
    var library = request.libraryElement;
    bool isVisible(Element element) => element.isAccessibleIn(library);
    var targetId = request.dotTarget;
    if (targetId is Identifier && !request.target.isCascade) {
      var element = targetId.staticElement;
      if (element is TypeAliasElement) {
        var aliasedType = element.aliasedType;
        element = aliasedType.element;
      }
      if (element is ClassElement) {
        for (var accessor in element.accessors) {
          if (accessor.isStatic &&
              !accessor.isSynthetic &&
              isVisible(accessor)) {
            builder.suggestAccessor(accessor, inheritanceDistance: 0.0);
          }
        }
        if (!request.shouldSuggestTearOff(element)) {
          for (var constructor in element.constructors) {
            if (isVisible(constructor)) {
              if (!element.isAbstract || constructor.isFactory) {
                builder.suggestConstructor(constructor, hasClassName: true);
              }
            }
          }
        }
        for (var field in element.fields) {
          if (field.isStatic &&
              (!field.isSynthetic || element.isEnum) &&
              isVisible(field)) {
            builder.suggestField(field, inheritanceDistance: 0.0);
          }
        }
        for (var method in element.methods) {
          if (method.isStatic && isVisible(method)) {
            builder.suggestMethod(method, inheritanceDistance: 0.0);
          }
        }
      } else if (element is ExtensionElement) {
        for (var accessor in element.accessors) {
          if (accessor.isStatic &&
              !accessor.isSynthetic &&
              isVisible(accessor)) {
            builder.suggestAccessor(accessor, inheritanceDistance: 0.0);
          }
        }
        for (var field in element.fields) {
          if (field.isStatic && !field.isSynthetic && isVisible(field)) {
            builder.suggestField(field, inheritanceDistance: 0.0);
          }
        }
        for (var method in element.methods) {
          if (method.isStatic && isVisible(method)) {
            builder.suggestMethod(method, inheritanceDistance: 0.0);
          }
        }
      }
    }
  }
}
