// 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 'package:analysis_server/src/protocol_server.dart'
    show SearchResult, newSearchResult_fromMatch;
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/element/element.dart';

/// A computer for `search.findElementReferences` request results.
class ElementReferencesComputer {
  final SearchEngine searchEngine;

  ElementReferencesComputer(this.searchEngine);

  /// Computes [SearchMatch]es for [element] references.
  Future<List<SearchMatch>> compute(Element element, bool withPotential) async {
    var results = <SearchMatch>[];

    // Add element references.
    results.addAll(await _findElementsReferences(element));

    // Add potential references.
    if (withPotential && _isMemberElement(element)) {
      var name = element.displayName;
      var matches = await searchEngine.searchMemberReferences(name);
      results.addAll(matches.where((match) => !match.isResolved));
    }

    return results;
  }

  /// Returns a [Future] completing with a [List] of references to [element] or
  /// to the corresponding hierarchy [Element]s.
  Future<List<SearchMatch>> _findElementsReferences(Element element) async {
    var allResults = <SearchMatch>[];
    var refElements = await _getRefElements(element);
    for (var refElement in refElements) {
      var elementResults = await _findSingleElementReferences(refElement);
      allResults.addAll(elementResults);
    }
    return allResults;
  }

  /// Returns a [Future] completing with a [List] of references to [element].
  Future<List<SearchMatch>> _findSingleElementReferences(
      Element element) async {
    return searchEngine.searchReferences(element);
  }

  /// Returns a [Future] completing with [Element]s to search references to.
  ///
  /// If a [ClassMemberElement] or a named [ParameterElement] is given, each
  /// corresponding [Element] in the hierarchy is returned.
  ///
  /// Otherwise, only references to [element] should be searched.
  Future<Iterable<Element>> _getRefElements(Element element) {
    if (element is ParameterElement && element.isNamed) {
      return getHierarchyNamedParameters(searchEngine, element);
    }
    if (element is ClassMemberElement) {
      return getHierarchyMembers(searchEngine, element);
    }
    return Future.value([element]);
  }

  static SearchResult toResult(SearchMatch match) {
    return newSearchResult_fromMatch(match);
  }

  static bool _isMemberElement(Element element) {
    if (element is ConstructorElement) {
      return false;
    }
    return element.enclosingElement is ClassElement;
  }
}
