// Copyright (c) 2015, 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/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/completion_core.dart'
    show AbortCompletion, CompletionContributor, CompletionRequest;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/completion_core.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/label_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/local_constructor_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/override_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:analyzer_plugin/src/utilities/completion/optype.dart';

/// [DartCompletionManager] determines if a completion request is Dart specific
/// and forwards those requests to all [DartCompletionContributor]s.
class DartCompletionManager implements CompletionContributor {
  /// The [contributionSorter] is a long-lived object that isn't allowed
  /// to maintain state between calls to [DartContributionSorter#sort(...)].
  static DartContributionSorter contributionSorter = CommonUsageSorter();

  /// The object used to resolve macros in Dartdoc comments.
  final DartdocDirectiveInfo dartdocDirectiveInfo;

  /// If not `null`, then instead of using [ImportedReferenceContributor],
  /// fill this set with kinds of elements that are applicable at the
  /// completion location, so should be suggested from available suggestion
  /// sets.
  final Set<protocol.ElementKind> includedElementKinds;

  /// If [includedElementKinds] is not null, must be also not `null`, and
  /// will be filled with names of all top-level declarations from all
  /// included suggestion sets.
  final Set<String> includedElementNames;

  /// If [includedElementKinds] is not null, must be also not `null`, and
  /// will be filled with tags for suggestions that should be given higher
  /// relevance than other included suggestions.
  final List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;

  /// Initialize a newly created completion manager. The parameters
  /// [includedElementKinds], [includedElementNames], and
  /// [includedSuggestionRelevanceTags] must either all be `null` or must all be
  /// non-`null`.
  DartCompletionManager({
    this.dartdocDirectiveInfo,
    this.includedElementKinds,
    this.includedElementNames,
    this.includedSuggestionRelevanceTags,
  }) : assert((includedElementKinds != null &&
                includedElementNames != null &&
                includedSuggestionRelevanceTags != null) ||
            (includedElementKinds == null &&
                includedElementNames == null &&
                includedSuggestionRelevanceTags == null));

  @override
  Future<List<CompletionSuggestion>> computeSuggestions(
      CompletionRequest request) async {
    request.checkAborted();
    if (!AnalysisEngine.isDartFileName(request.result.path)) {
      return const <CompletionSuggestion>[];
    }

    var performance = (request as CompletionRequestImpl).performance;
    DartCompletionRequestImpl dartRequest =
        await DartCompletionRequestImpl.from(request, dartdocDirectiveInfo);

    // Don't suggest in comments.
    if (dartRequest.target.isCommentText) {
      return const <CompletionSuggestion>[];
    }

    final ranking = CompletionRanking.instance;
    var probabilityFuture =
        ranking != null ? ranking.predict(dartRequest) : Future.value(null);

    var range = dartRequest.target.computeReplacementRange(dartRequest.offset);
    (request as CompletionRequestImpl)
      ..replacementOffset = range.offset
      ..replacementLength = range.length;

    // Request Dart specific completions from each contributor
    var suggestionMap = <String, CompletionSuggestion>{};
    var constructorMap = <String, List<String>>{};
    var builder = SuggestionBuilder(dartRequest);
    var contributors = <DartCompletionContributor>[
      ArgListContributor(),
      CombinatorContributor(),
      ExtensionMemberContributor(),
      FieldFormalContributor(),
      InheritedReferenceContributor(),
      KeywordContributor(),
      LabelContributor(),
      LibraryMemberContributor(),
      LibraryPrefixContributor(),
      LocalConstructorContributor(),
      LocalLibraryContributor(),
      LocalReferenceContributor(),
      NamedConstructorContributor(),
      OverrideContributor(),
      StaticMemberContributor(),
      TypeMemberContributor(),
      UriContributor(),
      VariableNameContributor()
    ];

    if (includedElementKinds != null) {
      _addIncludedElementKinds(dartRequest);
      _addIncludedSuggestionRelevanceTags(dartRequest);
    } else {
      contributors.add(ImportedReferenceContributor());
    }

    void addSuggestionToMap(CompletionSuggestion newSuggestion) {
      // TODO(brianwilkerson) After all contributors are using SuggestionBuilder
      //  move this logic into SuggestionBuilder.
      var key = newSuggestion.completion;

      // Append parenthesis for constructors to disambiguate from classes.
      if (_isConstructor(newSuggestion)) {
        key += '()';
        var className = _getConstructorClassName(newSuggestion);
        _ensureList(constructorMap, className).add(key);
      }

      // Local declarations hide both the class and its constructors.
      if (!_isClass(newSuggestion)) {
        var constructorKeys = constructorMap[key];
        constructorKeys?.forEach(suggestionMap.remove);
      }

      var oldSuggestion = suggestionMap[key];
      if (oldSuggestion == null ||
          oldSuggestion.relevance < newSuggestion.relevance) {
        suggestionMap[key] = newSuggestion;
      }
    }

    try {
      for (var contributor in contributors) {
        var contributorTag =
            'DartCompletionManager - ${contributor.runtimeType}';
        performance.logStartTime(contributorTag);
        var contributorSuggestions =
            await contributor.computeSuggestions(dartRequest, builder);
        performance.logElapseTime(contributorTag);
        request.checkAborted();

        for (var newSuggestion in contributorSuggestions) {
          addSuggestionToMap(newSuggestion);
        }
      }
      for (var newSuggestion in builder.suggestions) {
        addSuggestionToMap(newSuggestion);
      }
    } on InconsistentAnalysisException {
      // The state of the code being analyzed has changed, so results are likely
      // to be inconsistent. Just abort the operation.
      throw AbortCompletion();
    }

    // Adjust suggestion relevance before returning
    var suggestions = suggestionMap.values.toList();
    const SORT_TAG = 'DartCompletionManager - sort';
    performance.logStartTime(SORT_TAG);
    if (ranking != null) {
      request.checkAborted();
      try {
        suggestions = await ranking.rerank(
            probabilityFuture,
            suggestions,
            includedElementNames,
            includedSuggestionRelevanceTags,
            dartRequest,
            request.result.unit.featureSet);
      } catch (exception, stackTrace) {
        // TODO(brianwilkerson) Shutdown the isolates that have already been
        //  started.
        // Disable smart ranking if prediction fails.
        CompletionRanking.instance = null;
        AnalysisEngine.instance.instrumentationService.logException(
            CaughtException.withMessage(
                'Failed to rerank completion suggestions',
                exception,
                stackTrace));
        await contributionSorter.sort(dartRequest, suggestions);
      }
    } else if (!request.useNewRelevance) {
      await contributionSorter.sort(dartRequest, suggestions);
    }
    performance.logElapseTime(SORT_TAG);
    request.checkAborted();
    return suggestions;
  }

  void _addIncludedElementKinds(DartCompletionRequestImpl request) {
    var opType = request.opType;

    if (!opType.includeIdentifiers) return;

    var kinds = includedElementKinds;
    if (kinds != null) {
      if (opType.includeConstructorSuggestions) {
        kinds.add(protocol.ElementKind.CONSTRUCTOR);
      }
      if (opType.includeTypeNameSuggestions) {
        kinds.add(protocol.ElementKind.CLASS);
        kinds.add(protocol.ElementKind.CLASS_TYPE_ALIAS);
        kinds.add(protocol.ElementKind.ENUM);
        kinds.add(protocol.ElementKind.FUNCTION_TYPE_ALIAS);
        kinds.add(protocol.ElementKind.MIXIN);
      }
      if (opType.includeReturnValueSuggestions) {
        kinds.add(protocol.ElementKind.CONSTRUCTOR);
        kinds.add(protocol.ElementKind.ENUM_CONSTANT);
        kinds.add(protocol.ElementKind.EXTENSION);
        // Static fields.
        kinds.add(protocol.ElementKind.FIELD);
        kinds.add(protocol.ElementKind.FUNCTION);
        // Static and top-level properties.
        kinds.add(protocol.ElementKind.GETTER);
        kinds.add(protocol.ElementKind.SETTER);
        kinds.add(protocol.ElementKind.TOP_LEVEL_VARIABLE);
      }
    }
  }

  void _addIncludedSuggestionRelevanceTags(DartCompletionRequestImpl request) {
    var target = request.target;

    void addTypeTag(DartType type) {
      if (type is InterfaceType) {
        var element = type.element;
        var tag = '${element.librarySource.uri}::${element.name}';
        if (element.isEnum) {
          includedSuggestionRelevanceTags.add(
            IncludedSuggestionRelevanceTag(
              tag,
              DART_RELEVANCE_BOOST_AVAILABLE_ENUM,
            ),
          );
        } else {
          includedSuggestionRelevanceTags.add(
            IncludedSuggestionRelevanceTag(
              tag,
              DART_RELEVANCE_BOOST_AVAILABLE_DECLARATION,
            ),
          );
        }
      }
    }

    var parameter = target.parameterElement;
    if (parameter != null) {
      addTypeTag(parameter.type);
    }

    var containingNode = target.containingNode;

    if (containingNode is AssignmentExpression &&
        containingNode.operator.type == TokenType.EQ &&
        target.offset >= containingNode.operator.end) {
      addTypeTag(containingNode.leftHandSide.staticType);
    }

    if (containingNode is ListLiteral &&
        target.offset >= containingNode.leftBracket.end &&
        target.offset <= containingNode.rightBracket.offset) {
      var type = containingNode.staticType;
      if (type is InterfaceType) {
        var typeArguments = type.typeArguments;
        if (typeArguments.isNotEmpty) {
          addTypeTag(typeArguments[0]);
        }
      }
    }

    if (containingNode is VariableDeclaration &&
        containingNode.equals != null &&
        target.offset >= containingNode.equals.end) {
      var parent = containingNode.parent;
      if (parent is VariableDeclarationList) {
        var type = parent.type?.type;
        if (type is InterfaceType) {
          addTypeTag(type);
        }
      }
    }
  }

  static List<String> _ensureList(Map<String, List<String>> map, String key) {
    var list = map[key];
    if (list == null) {
      list = <String>[];
      map[key] = list;
    }
    return list;
  }

  static String _getConstructorClassName(CompletionSuggestion suggestion) {
    var completion = suggestion.completion;
    var dotIndex = completion.indexOf('.');
    if (dotIndex != -1) {
      return completion.substring(0, dotIndex);
    } else {
      return completion;
    }
  }

  static bool _isClass(CompletionSuggestion suggestion) {
    return suggestion.element?.kind == protocol.ElementKind.CLASS;
  }

  static bool _isConstructor(CompletionSuggestion suggestion) {
    return suggestion.element?.kind == protocol.ElementKind.CONSTRUCTOR;
  }
}

/// The information about a requested list of completions within a Dart file.
class DartCompletionRequestImpl implements DartCompletionRequest {
  @override
  final ResolvedUnitResult result;

  @override
  final ResourceProvider resourceProvider;

  @override
  final InterfaceType objectType;

  @override
  final Source source;

  @override
  final int offset;

  @override
  Expression dotTarget;

  @override
  final Source librarySource;

  @override
  CompletionTarget target;

  OpType _opType;

  @override
  final FeatureComputer featureComputer;

  @override
  final DartdocDirectiveInfo dartdocDirectiveInfo;

  /// A flag indicating whether the [_contextType] has been computed.
  bool _hasComputedContextType = false;

  /// The context type associated with the target's `containingNode`.
  DartType _contextType;

  final CompletionRequest _originalRequest;

  final CompletionPerformance performance;

  DartCompletionRequestImpl._(
      this.result,
      this.resourceProvider,
      this.objectType,
      this.librarySource,
      this.source,
      this.offset,
      CompilationUnit unit,
      this.dartdocDirectiveInfo,
      this._originalRequest,
      this.performance)
      : featureComputer =
            FeatureComputer(result.typeSystem, result.typeProvider) {
    _updateTargets(unit);
  }

  @override
  DartType get contextType {
    if (!_hasComputedContextType) {
      _contextType = featureComputer.computeContextType(target.containingNode);
      _hasComputedContextType = true;
    }
    return _contextType;
  }

  @override
  FeatureSet get featureSet =>
      result.session.analysisContext.analysisOptions.contextFeatures;

  @override
  bool get includeIdentifiers {
    return opType.includeIdentifiers;
  }

  @override
  LibraryElement get libraryElement {
    //TODO(danrubel) build the library element rather than all the declarations
    var unit = target.unit;
    if (unit != null) {
      var elem = unit.declaredElement;
      if (elem != null) {
        return elem.library;
      }
    }
    return null;
  }

  @override
  OpType get opType {
    _opType ??= OpType.forCompletion(target, offset);
    return _opType;
  }

  @override
  String get sourceContents => result.content;

  @override
  SourceFactory get sourceFactory {
    DriverBasedAnalysisContext context = result.session.analysisContext;
    return context.driver.sourceFactory;
  }

  @override
  bool get useNewRelevance => _originalRequest.useNewRelevance;

  /// Throw [AbortCompletion] if the completion request has been aborted.
  @override
  void checkAborted() {
    _originalRequest.checkAborted();
  }

  /// Update the completion [target] and [dotTarget] based on the given [unit].
  void _updateTargets(CompilationUnit unit) {
    _opType = null;
    dotTarget = null;
    target = CompletionTarget.forOffset(unit, offset);
    var node = target.containingNode;
    if (node is MethodInvocation) {
      if (identical(node.methodName, target.entity)) {
        dotTarget = node.realTarget;
      } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
        dotTarget = node.realTarget;
      }
    }
    if (node is PropertyAccess) {
      if (identical(node.propertyName, target.entity)) {
        dotTarget = node.realTarget;
      } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
        dotTarget = node.realTarget;
      }
    }
    if (node is PrefixedIdentifier) {
      if (identical(node.identifier, target.entity)) {
        dotTarget = node.prefix;
      }
    }
  }

  /// Return a [Future] that completes with a newly created completion request
  /// based on the given [request]. This method will throw [AbortCompletion]
  /// if the completion request has been aborted.
  static Future<DartCompletionRequest> from(CompletionRequest request,
      DartdocDirectiveInfo dartdocDirectiveInfo) async {
    request.checkAborted();
    var performance = (request as CompletionRequestImpl).performance;
    const BUILD_REQUEST_TAG = 'build DartCompletionRequest';
    performance.logStartTime(BUILD_REQUEST_TAG);

    var unit = request.result.unit;
    var libSource = unit.declaredElement.library.source;
    var objectType = request.result.typeProvider.objectType;

    var dartRequest = DartCompletionRequestImpl._(
        request.result,
        request.resourceProvider,
        objectType,
        libSource,
        request.source,
        request.offset,
        unit,
        dartdocDirectiveInfo,
        request,
        performance);

    performance.logElapseTime(BUILD_REQUEST_TAG);
    return dartRequest;
  }
}
