// 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/optype.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.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;
    return _computeSuggestionsForClass2(resolutionMap
        .elementDeclaredByClassDeclaration(classDecl), request);
  }

  List<CompletionSuggestion> _computeSuggestionsForClass2(
      ClassElement classElement, DartCompletionRequest request,
      {bool skipChildClass: true}) {
    bool isFunctionalArgument = request.target.isFunctionalArgument();
    kind = isFunctionalArgument
        ? CompletionSuggestionKind.IDENTIFIER
        : CompletionSuggestionKind.INVOCATION;
    OpType optype = request.opType;

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

    for (InterfaceType type in classElement.allSupertypes) {
      _addSuggestionsForType(type, optype,
          isFunctionalArgument: isFunctionalArgument);
    }
    return suggestions;
  }

  List<CompletionSuggestion> computeSuggestionsForClass(
      ClassElement classElement, DartCompletionRequest request,
      {bool skipChildClass: true}) {
    if (!request.includeIdentifiers) {
      return EMPTY_LIST;
    }
    containingLibrary = request.libraryElement;

    return _computeSuggestionsForClass2(classElement, request,
        skipChildClass: skipChildClass);
  }

  _addSuggestionsForType(InterfaceType type, OpType optype,
      {bool isFunctionalArgument: false}) {
    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);
        }
      }
    }
  }
}
