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

import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/ast/ast.dart';

/// A contributor that produces suggestions for constructors that are being
/// redirected to. More concretely, this class produces suggestions for
/// expressions of the form `this.^` or `super.^` in a constructor's initializer
/// list or after an `=` in a factory constructor.
class RedirectingContributor extends DartCompletionContributor {
  @override
  Future<void> computeSuggestions(
      DartCompletionRequest request, SuggestionBuilder builder) async {
    var entity = request.target.entity;
    if (entity is SimpleIdentifier) {
      var parent = entity.parent;
      if (parent is PropertyAccess &&
          parent.parent is ConstructorFieldInitializer) {
        // C() : this.^
        var containingConstructor =
            parent.thisOrAncestorOfType<ConstructorDeclaration>();
        var constructorElement = containingConstructor?.declaredElement;
        var containingClass = containingConstructor
            ?.thisOrAncestorOfType<ClassOrMixinDeclaration>();
        var classElement = containingClass?.declaredElement;
        if (classElement != null) {
          for (var constructor in classElement.constructors) {
            if (constructor != constructorElement) {
              builder.suggestConstructor(constructor, hasClassName: true);
            }
          }
        }
      } else if (parent is SuperConstructorInvocation) {
        // C() : super.^
        var containingClass =
            parent.thisOrAncestorOfType<ClassOrMixinDeclaration>();
        var superclassElement =
            containingClass?.declaredElement?.supertype?.element;
        if (superclassElement != null) {
          for (var constructor in superclassElement.constructors) {
            if (constructor.isAccessibleIn(request.libraryElement)) {
              builder.suggestConstructor(constructor, hasClassName: true);
            }
          }
        }
      }
    } else if (entity is ConstructorName) {
      var parent = entity.parent;
      if (parent is ConstructorDeclaration &&
          parent.redirectedConstructor == entity) {
        // factory C() = ^
        var containingConstructor =
            parent.thisOrAncestorOfType<ConstructorDeclaration>();
        var constructorElement = containingConstructor?.declaredElement;
        var containingClass =
            parent.thisOrAncestorOfType<ClassOrMixinDeclaration>();
        var classElement = containingClass?.declaredElement;
        var libraryElement = request.libraryElement;
        if (classElement == null) {
          return;
        }
        var typeSystem = libraryElement.typeSystem;
        for (var unit in libraryElement.units) {
          for (var class_ in unit.classes) {
            if (typeSystem.isSubtypeOf(
                class_.thisType, classElement.thisType)) {
              for (var constructor in class_.constructors) {
                if (constructor != constructorElement &&
                    constructor.isAccessibleIn(request.libraryElement)) {
                  builder.suggestConstructor(constructor);
                }
              }
            }
          }
        }
      }
    }
  }
}
