// Copyright (c) 2017, 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:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:analyzer_plugin/src/utilities/completion/element_suggestion_builder.dart';
import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
import 'package:analyzer_plugin/utilities/completion/completion_core.dart';

/// A contributor for calculating suggestions for inherited references.
///
/// Plugin developers should extend this function and primarily overload
/// `computeSuggestions` (if needed).
class InheritedReferenceContributor
    with ElementSuggestionBuilder
    implements CompletionContributor {
  @override
  LibraryElement? containingLibrary;

  @override
  CompletionSuggestionKind? kind;

  @override
  ResourceProvider? resourceProvider;

  /// Plugin contributors should primarily overload this function. Should more
  /// parameters be needed for autocompletion needs, the overloaded function
  /// should define those parameters and call on `computeSuggestionsForClass`.
  @override
  Future<void> computeSuggestions(
      DartCompletionRequest request, CompletionCollector collector) async {
    var target =
        CompletionTarget.forOffset(request.result.unit!, request.offset);
    var optype = OpType.forCompletion(target, request.offset);
    if (!optype.includeIdentifiers) {
      return;
    }
    var classDecl = _enclosingClass(target);
    if (classDecl == null || classDecl.declaredElement == null) {
      return;
    }
    containingLibrary = request.result.libraryElement;
    _computeSuggestionsForClass2(
        collector, target, classDecl.declaredElement!, optype);
  }

  /// Clients should not overload this function.
  Future<void> computeSuggestionsForClass(
    DartCompletionRequest request,
    CompletionCollector collector,
    ClassElement? classElement, {
    AstNode? entryPoint,
    bool skipChildClass = true,
    CompletionTarget? target,
    OpType? optype,
  }) async {
    target ??= CompletionTarget.forOffset(request.result.unit!, request.offset,
        entryPoint: entryPoint);
    optype ??= OpType.forCompletion(target, request.offset);
    if (!optype.includeIdentifiers) {
      return;
    }
    if (classElement == null) {
      var classDecl = _enclosingClass(target);
      if (classDecl == null || classDecl.declaredElement == null) {
        return;
      }
      classElement = classDecl.declaredElement;
    }
    containingLibrary = request.result.libraryElement;
    _computeSuggestionsForClass2(collector, target, classElement!, optype,
        skipChildClass: skipChildClass);
  }

  void _addSuggestionsForType(InterfaceType type, OpType optype,
      {bool isFunctionalArgument = false}) {
    if (!isFunctionalArgument) {
      for (var elem in type.accessors) {
        if (elem.isGetter) {
          if (optype.includeReturnValueSuggestions) {
            addSuggestion(elem);
          }
        } else {
          if (optype.includeVoidReturnSuggestions) {
            addSuggestion(elem);
          }
        }
      }
    }
    for (var elem in type.methods) {
      if (!elem.returnType.isVoid) {
        if (optype.includeReturnValueSuggestions) {
          addSuggestion(elem);
        }
      } else {
        if (optype.includeVoidReturnSuggestions) {
          addSuggestion(elem);
        }
      }
    }
  }

  void _computeSuggestionsForClass2(CompletionCollector collector,
      CompletionTarget target, ClassElement classElement, OpType optype,
      {bool skipChildClass = true}) {
    var isFunctionalArgument = target.isFunctionalArgument();
    kind = isFunctionalArgument
        ? CompletionSuggestionKind.IDENTIFIER
        : CompletionSuggestionKind.INVOCATION;

    if (!skipChildClass) {
      _addSuggestionsForType(classElement.thisType, optype,
          isFunctionalArgument: isFunctionalArgument);
    }

    for (var type in classElement.allSupertypes) {
      _addSuggestionsForType(type, optype,
          isFunctionalArgument: isFunctionalArgument);
    }
    for (var suggestion in suggestions) {
      collector.addSuggestion(suggestion);
    }
  }

  /// Return the class containing the target or `null` if the target is in a
  /// static method or field or not in a class.
  ClassDeclaration? _enclosingClass(CompletionTarget? target) {
    var node = target?.containingNode;
    while (node != null) {
      if (node is ClassDeclaration) {
        return node;
      }
      if (node is MethodDeclaration) {
        if (node.isStatic) {
          return null;
        }
      }
      if (node is FieldDeclaration) {
        if (node.isStatic) {
          return null;
        }
      }
      node = node.parent;
    }
    return null;
  }
}
