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

library services.completion.contributor.dart.inherited_ref;

import 'dart:async';

import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/optype.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';

import '../../../protocol_server.dart'
    show CompletionSuggestion, CompletionSuggestionKind;

/**
 * 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) {
  AstNode 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;
}

/**
 * A contributor for calculating suggestions for inherited references.
 */
class InheritedReferenceContributor extends DartCompletionContributor
    with ElementSuggestionBuilder {
  @override
  LibraryElement containingLibrary;

  @override
  CompletionSuggestionKind kind;

  @override
  Future<List<CompletionSuggestion>> computeSuggestions(
      DartCompletionRequest request) async {
    if (!request.includeIdentifiers) {
      return EMPTY_LIST;
    }
    ClassDeclaration classDecl = _enclosingClass(request.target);
    if (classDecl == null || classDecl.element == null) {
      return EMPTY_LIST;
    }

    containingLibrary = request.libraryElement;
    bool isFunctionalArgument = request.target.isFunctionalArgument();
    kind = isFunctionalArgument
        ? CompletionSuggestionKind.IDENTIFIER
        : CompletionSuggestionKind.INVOCATION;
    OpType optype = (request as DartCompletionRequestImpl).opType;
    for (InterfaceType type in classDecl.element.allSupertypes) {
      if (!isFunctionalArgument) {
        for (PropertyAccessorElement elem in type.accessors) {
          if (elem.isGetter) {
            if (optype.includeReturnValueSuggestions) {
              addSuggestion(elem);
            }
          } else {
            if (optype.includeVoidReturnSuggestions) {
              addSuggestion(elem);
            }
          }
        }
      }
      for (MethodElement elem in type.methods) {
        if (elem.returnType == null) {
          addSuggestion(elem);
        } else if (!elem.returnType.isVoid) {
          if (optype.includeReturnValueSuggestions) {
            addSuggestion(elem);
          }
        } else {
          if (optype.includeVoidReturnSuggestions) {
            addSuggestion(elem);
          }
        }
      }
    }
    return suggestions;
  }
}
