// 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/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/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/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.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 = new CommonUsageSorter();

  /// 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 tags for suggestions that should be given higher
  /// relevance than other included suggestions.
  final List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;

  DartCompletionManager({
    this.includedElementKinds,
    this.includedSuggestionRelevanceTags,
  });

  @override
  Future<List<CompletionSuggestion>> computeSuggestions(
      CompletionRequest request) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    request.checkAborted();
    if (!AnalysisEngine.isDartFileName(request.result.path)) {
      return const <CompletionSuggestion>[];
    }

    CompletionPerformance performance =
        (request as CompletionRequestImpl).performance;
    DartCompletionRequestImpl dartRequest =
        await DartCompletionRequestImpl.from(request);

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

    final ranking = CompletionRanking.instance;
    Future<Map<String, double>> probabilityFuture =
        ranking != null ? ranking.predict(dartRequest) : Future.value(null);

    SourceRange 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>>{};
    List<DartCompletionContributor> contributors = <DartCompletionContributor>[
      new ArgListContributor(),
      new CombinatorContributor(),
      new ExtensionMemberContributor(),
      new FieldFormalContributor(),
      new InheritedReferenceContributor(),
      new KeywordContributor(),
      new LabelContributor(),
      new LibraryMemberContributor(),
      new LibraryPrefixContributor(),
      new LocalConstructorContributor(),
      new LocalLibraryContributor(),
      new LocalReferenceContributor(),
      new NamedConstructorContributor(),
      new OverrideContributor(),
      new StaticMemberContributor(),
      new TypeMemberContributor(),
      new UriContributor(),
      new VariableNameContributor()
    ];

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

    try {
      for (DartCompletionContributor contributor in contributors) {
        String contributorTag =
            'DartCompletionManager - ${contributor.runtimeType}';
        performance.logStartTime(contributorTag);
        List<CompletionSuggestion> contributorSuggestions =
            await contributor.computeSuggestions(dartRequest);
        performance.logElapseTime(contributorTag);
        request.checkAborted();

        for (CompletionSuggestion newSuggestion in contributorSuggestions) {
          String key = newSuggestion.completion;

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

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

          CompletionSuggestion oldSuggestion = suggestionMap[key];
          if (oldSuggestion == null ||
              oldSuggestion.relevance < newSuggestion.relevance) {
            suggestionMap[key] = newSuggestion;
          }
        }
      }
    } on InconsistentAnalysisException {
      // The state of the code being analyzed has changed, so results are likely
      // to be inconsistent. Just abort the operation.
      throw new AbortCompletion();
    }

    // Adjust suggestion relevance before returning
    List<CompletionSuggestion> suggestions = suggestionMap.values.toList();
    const SORT_TAG = 'DartCompletionManager - sort';
    performance.logStartTime(SORT_TAG);
    await contributionSorter.sort(dartRequest, suggestions);
    if (ranking != null) {
      request.checkAborted();
      suggestions = await ranking.rerank(
          probabilityFuture,
          suggestions,
          includedSuggestionRelevanceTags,
          dartRequest,
          request.result.unit.featureSet);
    }
    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);
        kinds.add(protocol.ElementKind.FUNCTION);
        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) {
    List<String> list = map[key];
    if (list == null) {
      list = <String>[];
      map[key] = list;
    }
    return list;
  }

  static String _getConstructorClassName(CompletionSuggestion suggestion) {
    String completion = suggestion.completion;
    int 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;

  final CompletionRequest _originalRequest;

  final CompletionPerformance performance;

  DartCompletionRequestImpl._(
      this.result,
      this.resourceProvider,
      this.objectType,
      this.librarySource,
      this.source,
      this.offset,
      CompilationUnit unit,
      this._originalRequest,
      this.performance) {
    _updateTargets(unit);
  }

  @override
  List<String> get enabledExperiments =>
      result.session.analysisContext.analysisOptions.enabledExperiments;

  @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
    CompilationUnit unit = target.unit;
    if (unit != null) {
      CompilationUnitElement elem = unit.declaredElement;
      if (elem != null) {
        return elem.library;
      }
    }
    return null;
  }

  OpType get opType {
    if (_opType == null) {
      _opType = new 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;
  }

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

  /**
   * Update the completion [target] and [dotTarget] based on the given [unit].
   */
  void _updateTargets(CompilationUnit unit) {
    _opType = null;
    dotTarget = null;
    target = new CompletionTarget.forOffset(unit, offset);
    AstNode 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) async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    request.checkAborted();
    CompletionPerformance performance =
        (request as CompletionRequestImpl).performance;
    const BUILD_REQUEST_TAG = 'build DartCompletionRequest';
    performance.logStartTime(BUILD_REQUEST_TAG);

    CompilationUnit unit = request.result.unit;
    Source libSource = unit.declaredElement.library.source;
    InterfaceType objectType = request.result.typeProvider.objectType;

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

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