// 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:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';

/// Instances of the enum [MatchKind] represent the kind of reference that was
/// found when a match represents a reference to an element.
class MatchKind {
  /// A declaration of an element.
  static const MatchKind DECLARATION = MatchKind('DECLARATION');

  /// A reference to an element in which it is being read.
  static const MatchKind READ = MatchKind('READ');

  /// A reference to an element in which it is being both read and written.
  static const MatchKind READ_WRITE = MatchKind('READ_WRITE');

  /// A reference to an element in which it is being written.
  static const MatchKind WRITE = MatchKind('WRITE');

  /// A reference to an element in which it is being invoked.
  static const MatchKind INVOCATION = MatchKind('INVOCATION');

  /// A reference to an element in which it is referenced.
  static const MatchKind REFERENCE = MatchKind('REFERENCE');

  final String name;

  const MatchKind(this.name);

  @override
  String toString() => name;
}

/// The interface [SearchEngine] defines the behavior of objects that can be
/// used to search for various pieces of information.
abstract class SearchEngine {
  /// If the [type] has subtypes, return the set of names of members which these
  /// subtypes declare, possibly empty.  If the [type] does not have subtypes,
  /// return `null`.
  Future<Set<String>> membersOfSubtypes(ClassElement type);

  /// Returns all subtypes of the given [type].
  ///
  /// [type] - the [ClassElement] being subtyped by the found matches.
  Future<Set<ClassElement>> searchAllSubtypes(ClassElement type);

  /// Returns declarations of class members with the given name.
  ///
  /// [name] - the name being declared by the found matches.
  Future<List<SearchMatch>> searchMemberDeclarations(String name);

  /// Returns all resolved and unresolved qualified references to the class
  /// members with given [name].
  ///
  /// [name] - the name being referenced by the found matches.
  Future<List<SearchMatch>> searchMemberReferences(String name);

  /// Returns references to the given [Element].
  ///
  /// [element] - the [Element] being referenced by the found matches.
  Future<List<SearchMatch>> searchReferences(Element element);

  /// Returns direct subtypes of the given [type].
  ///
  /// [type] - the [ClassElement] being subtyped by the found matches.
  Future<List<SearchMatch>> searchSubtypes(ClassElement type);

  /// Returns all the top-level declarations matching the given pattern.
  ///
  /// [pattern] the regular expression used to match the names of the
  ///    declarations to be found.
  Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern);
}

/// Instances of the class [SearchMatch] represent a match found by
/// [SearchEngine].
abstract class SearchMatch {
  /// Return the [Element] containing the match. Can return `null` if the unit
  /// does not exist, or its element was invalidated, or the element cannot be
  /// found, etc.
  Element get element;

  /// The absolute path of the file containing the match.
  String get file;

  /// Is `true` if field or method access is done using qualifier.
  bool get isQualified;

  /// Is `true` if the match is a resolved reference to some [Element].
  bool get isResolved;

  /// The kind of the match.
  MatchKind get kind;

  /// Return the [LibraryElement] for the [file].
  LibraryElement get libraryElement;

  /// The library [Source] of the reference.
  Source get librarySource;

  /// The source range that was matched.
  SourceRange get sourceRange;

  /// The unit [Source] of the reference.
  Source get unitSource;

  /// Return elements of [matches] which has not-null elements.
  ///
  /// When [SearchMatch.element] is not `null` we cache its value, so it cannot
  /// become `null` later.
  static List<SearchMatch> withNotNullElement(List<SearchMatch> matches) {
    return matches.where((match) => match.element != null).toList();
  }
}
