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

import 'dart:async';

import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
    show createSuggestion, ElementSuggestionBuilder, SuggestionBuilder;
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer_plugin/src/utilities/completion/optype.dart';

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

/// A visitor for building suggestions based upon the elements defined by
/// a source file contained in the same library but not the same as
/// the source in which the completions are being requested.
class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
    with ElementSuggestionBuilder {
  @override
  final DartCompletionRequest request;

  final OpType optype;

  DartType contextType;

  @override
  CompletionSuggestionKind kind;

  final String prefix;

  /// The set of libraries that have been, or are currently being, visited.
  final Set<LibraryElement> visitedLibraries = <LibraryElement>{};

  LibraryElementSuggestionBuilder(this.request, [this.prefix])
      : optype = request.opType {
    contextType = request.featureComputer
        .computeContextType(request.target.containingNode);
    kind = request.target.isFunctionalArgument()
        ? CompletionSuggestionKind.IDENTIFIER
        : optype.suggestKind;
  }

  @override
  LibraryElement get containingLibrary => request.libraryElement;

  @override
  void visitClassElement(ClassElement element) {
    if (optype.includeTypeNameSuggestions) {
      // if includeTypeNameSuggestions, then use the filter
      int relevance;
      if (request.useNewRelevance) {
        relevance = _relevanceForType(element.thisType);
      } else if (element.hasDeprecated) {
        relevance = DART_RELEVANCE_LOW;
      } else {
        relevance = optype.typeNameSuggestionsFilter(
            _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
      }
      if (relevance != null) {
        addSuggestion(element, prefix: prefix, relevance: relevance);
      }
    }
    if (optype.includeConstructorSuggestions) {
      int relevance;
      if (request.useNewRelevance) {
        relevance = _relevanceForType(element.thisType);
      } else if (element.hasDeprecated) {
        relevance = DART_RELEVANCE_LOW;
      } else {
        relevance = optype.returnValueSuggestionsFilter(
            _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
      }
      _addConstructorSuggestions(element, relevance);
    }
    if (optype.includeReturnValueSuggestions) {
      if (element.isEnum) {
        var enumName = element.displayName;
        int relevance;
        if (request.useNewRelevance) {
          relevance = _relevanceForType(element.thisType);
        } else if (element.hasDeprecated) {
          relevance = DART_RELEVANCE_LOW;
        } else {
          relevance = optype.returnValueSuggestionsFilter(
              _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
        }
        for (var field in element.fields) {
          if (field.isEnumConstant) {
            addSuggestion(field,
                prefix: prefix,
                relevance: relevance,
                elementCompletion: '$enumName.${field.name}');
          }
        }
      }
    }
  }

  @override
  void visitCompilationUnitElement(CompilationUnitElement element) {
    element.visitChildren(this);
  }

  @override
  void visitElement(Element element) {
    // ignored
  }

  @override
  void visitExtensionElement(ExtensionElement element) {
    if (optype.includeReturnValueSuggestions) {
      int relevance;
      if (request.useNewRelevance) {
        relevance = _relevanceForType(element.extendedType);
      } else {
        relevance =
            element.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
      }
      addSuggestion(element, prefix: prefix, relevance: relevance);
    }
    element.visitChildren(this);
  }

  @override
  void visitFunctionElement(FunctionElement element) {
    // Do not suggest operators or local functions
    if (element.isOperator) {
      return;
    }
    if (element.enclosingElement is! CompilationUnitElement) {
      return;
    }
    var returnType = element.returnType;
    int relevance;
    if (request.useNewRelevance) {
      relevance = _relevanceForType(returnType);
    } else {
      relevance = element.hasDeprecated
          ? DART_RELEVANCE_LOW
          : (element.library == containingLibrary
              ? DART_RELEVANCE_LOCAL_FUNCTION
              : DART_RELEVANCE_DEFAULT);
    }
    if (returnType != null && returnType.isVoid) {
      if (optype.includeVoidReturnSuggestions) {
        addSuggestion(element, prefix: prefix, relevance: relevance);
      }
    } else {
      if (optype.includeReturnValueSuggestions) {
        addSuggestion(element, prefix: prefix, relevance: relevance);
      }
    }
  }

  @override
  void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
    if (optype.includeTypeNameSuggestions) {
      int relevance;
      if (request.useNewRelevance) {
        // TODO(brianwilkerson) Figure out whether there are any features that
        //  ought to be used here and what the right default value is.
        relevance = 400;
      } else {
        relevance = element.hasDeprecated
            ? DART_RELEVANCE_LOW
            : (element.library == containingLibrary
                ? DART_RELEVANCE_LOCAL_FUNCTION
                : DART_RELEVANCE_DEFAULT);
      }
      addSuggestion(element, prefix: prefix, relevance: relevance);
    }
  }

  @override
  void visitLibraryElement(LibraryElement element) {
    if (visitedLibraries.add(element)) {
      element.visitChildren(this);
    }
  }

  @override
  void visitPropertyAccessorElement(PropertyAccessorElement element) {
    if (optype.includeReturnValueSuggestions) {
      int relevance;
      if (request.useNewRelevance) {
        relevance = _relevanceForType(element.returnType);
      } else if (element.hasDeprecated) {
        relevance = DART_RELEVANCE_LOW;
      } else {
        if (element.library == containingLibrary) {
          if (element.enclosingElement is ClassElement) {
            relevance = DART_RELEVANCE_LOCAL_FIELD;
          } else {
            relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
          }
        } else {
          relevance = DART_RELEVANCE_DEFAULT;
        }
      }
      addSuggestion(element, prefix: prefix, relevance: relevance);
    }
  }

  @override
  void visitTopLevelVariableElement(TopLevelVariableElement element) {
    if (optype.includeReturnValueSuggestions) {
      int relevance;
      if (request.useNewRelevance) {
        relevance = _relevanceForType(element.type);
      } else {
        relevance = element.hasDeprecated
            ? DART_RELEVANCE_LOW
            : (element.library == containingLibrary
                ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
                : DART_RELEVANCE_DEFAULT);
      }
      addSuggestion(element, prefix: prefix, relevance: relevance);
    }
  }

  /// Add constructor suggestions for the given class.
  void _addConstructorSuggestions(ClassElement classElem, int relevance) {
    var className = classElem.name;
    for (var constructor in classElem.constructors) {
      if (constructor.isPrivate) {
        continue;
      }
      if (classElem.isAbstract && !constructor.isFactory) {
        continue;
      }

      var completion = constructor.displayName;
      completion = completion.isNotEmpty ? '$className.$completion' : className;
      if (prefix != null && prefix.isNotEmpty) {
        completion = '$prefix.$completion';
      }
      var suggestion = createSuggestion(request, constructor,
          completion: completion, relevance: relevance);
      if (suggestion != null) {
        suggestion.selectionOffset = suggestion.completion.length;
        suggestions.add(suggestion);
      }
    }
  }

  InterfaceType _instantiateClassElement(ClassElement element) {
    var typeParameters = element.typeParameters;
    var typeArguments = const <DartType>[];
    if (typeParameters.isNotEmpty) {
      var typeProvider = request.libraryElement.typeProvider;
      typeArguments = typeParameters.map((t) {
        return typeProvider.dynamicType;
      }).toList();
    }

    var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
        ? NullabilitySuffix.none
        : NullabilitySuffix.star;

    return element.instantiate(
      typeArguments: typeArguments,
      nullabilitySuffix: nullabilitySuffix,
    );
  }

  int _relevanceForType(DartType elementType) {
    var contextTypeFeature =
        request.featureComputer.contextTypeFeature(contextType, elementType);
    // TODO(brianwilkerson) Figure out whether there are other features that
    //  ought to be used here and what the right default value is.
    return toRelevance(contextTypeFeature, 800);
  }
}

/// A contributor that produces suggestions based on the top level members in
/// the library in which the completion is requested but outside the file in
/// which the completion is requested.
class LocalLibraryContributor extends DartCompletionContributor {
  @override
  Future<List<CompletionSuggestion>> computeSuggestions(
      DartCompletionRequest request, SuggestionBuilder builder) async {
    if (!request.includeIdentifiers) {
      return const <CompletionSuggestion>[];
    }

    var libraryUnits = request.result.unit.declaredElement.library.units;
    if (libraryUnits == null) {
      return const <CompletionSuggestion>[];
    }

    var visitor = LibraryElementSuggestionBuilder(request);
    for (var unit in libraryUnits) {
      if (unit != null && unit.source != request.source) {
        unit.accept(visitor);
      }
    }
    return visitor.suggestions;
  }
}
