// Copyright (c) 2016, 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.
library kernel.library_index;

import 'ast.dart';

/// Provides name-based access to library, class, and member AST nodes.
///
/// When constructed, a given set of libraries are indexed immediately, and
/// will not be up-to-date with changes made after it was created.
class LibraryIndex {
  static const String getterPrefix = 'get:';
  static const String setterPrefix = 'set:';
  static const String tearoffPrefix = 'get#';

  /// A special class name that can be used to access the top-level members
  /// of a library.
  static const String topLevel = '::';

  final Map<String, _ClassTable> _libraries = <String, _ClassTable>{};

  /// Indexes the libraries with the URIs given in [libraryUris].
  LibraryIndex(Component component, Iterable<String> libraryUris) {
    var libraryUriSet = libraryUris.toSet();
    for (var library in component.libraries) {
      var uri = '${library.importUri}';
      if (libraryUriSet.contains(uri)) {
        _libraries[uri] = new _ClassTable(library);
      }
    }
  }

  /// Indexes the libraries with the URIs given in [libraryUris].
  LibraryIndex.byUri(Component component, Iterable<Uri> libraryUris)
      : this(component, libraryUris.map((uri) => '$uri'));

  /// Indexes `dart:` libraries.
  LibraryIndex.coreLibraries(Component component) {
    for (var library in component.libraries) {
      if (library.importUri.scheme == 'dart') {
        _libraries['${library.importUri}'] = new _ClassTable(library);
      }
    }
  }

  /// Indexes the entire component.
  ///
  /// Consider using another constructor to only index the libraries that
  /// are needed.
  LibraryIndex.all(Component component) {
    for (var library in component.libraries) {
      _libraries['${library.importUri}'] = new _ClassTable(library);
    }
  }

  _ClassTable _getLibraryIndex(String uri) {
    _ClassTable libraryIndex = _libraries[uri];
    if (libraryIndex == null) {
      throw "The library '$uri' has not been indexed";
    }
    return libraryIndex;
  }

  /// Returns the library with the given URI.
  ///
  /// Throws an error if it does not exist.
  Library getLibrary(String uri) => _getLibraryIndex(uri).library;

  /// Like [getLibrary] but returns `null` if not found.
  Library tryGetLibrary(String uri) => _libraries[uri]?.library;

  /// True if the library with the given URI exists and was indexed.
  bool containsLibrary(String uri) => _libraries.containsKey(uri);

  /// Returns the class with the given name in the given library.
  ///
  /// An error is thrown if the class is not found.
  Class getClass(String library, String className) {
    return _getLibraryIndex(library).getClass(className);
  }

  /// Like [getClass] but returns `null` if not found.
  Class tryGetClass(String library, String className) {
    return _libraries[library]?.tryGetClass(className);
  }

  /// Returns the member with the given name, in the given class, in the
  /// given library.
  ///
  /// If a getter or setter is wanted, the `get:` or `set:` prefix must be
  /// added in front of the member name.
  ///
  /// The special class name `::` can be used to access top-level members.
  ///
  /// If the member name is private it is considered private to [library].
  /// It is not possible with this class to lookup members whose name is private
  /// to a library other than the one containing it.
  ///
  /// An error is thrown if the member is not found.
  Member getMember(String library, String className, String memberName) {
    return _getLibraryIndex(library).getMember(className, memberName);
  }

  /// Like [getMember] but returns `null` if not found.
  Member tryGetMember(String library, String className, String memberName) {
    return _libraries[library]?.tryGetMember(className, memberName);
  }

  /// Returns the top-level member with the given name, in the given library.
  ///
  /// If a getter or setter is wanted, the `get:` or `set:` prefix must be
  /// added in front of the member name.
  ///
  /// If the member name is private it is considered private to [library].
  /// It is not possible with this class to lookup members whose name is private
  /// to a library other than the one containing it.
  ///
  /// An error is thrown if the member is not found.
  Member getTopLevelMember(String library, String memberName) {
    return getMember(library, topLevel, memberName);
  }

  /// Like [getTopLevelMember] but returns `null` if not found.
  Member tryGetTopLevelMember(
      String library, String className, String memberName) {
    return tryGetMember(library, topLevel, memberName);
  }
}

class _ClassTable {
  final Library library;

  Map<String, _MemberTable> _classes;

  _ClassTable(this.library);

  Map<String, _MemberTable> get classes {
    if (_classes == null) {
      _classes = <String, _MemberTable>{};
      _classes[LibraryIndex.topLevel] = new _MemberTable.topLevel(this);
      for (var class_ in library.classes) {
        _classes[class_.name] = new _MemberTable.fromClass(this, class_);
      }
      for (var extension_ in library.extensions) {
        _classes[extension_.name] =
            new _MemberTable.fromExtension(this, extension_);
      }
      for (Reference reference in library.additionalExports) {
        NamedNode node = reference.node;
        if (node is Class) {
          _classes[node.name] = new _MemberTable.fromClass(this, node);
        } else if (node is Extension) {
          _classes[node.name] = new _MemberTable.fromExtension(this, node);
        }
      }
    }
    return _classes;
  }

  String get containerName {
    return "library '${library.importUri}'";
  }

  _MemberTable _getClassIndex(String name) {
    var indexer = classes[name];
    if (indexer == null) {
      throw "Class '$name' not found in $containerName";
    }
    return indexer;
  }

  Class getClass(String name) {
    return _getClassIndex(name).class_;
  }

  Class tryGetClass(String name) {
    return classes[name]?.class_;
  }

  Member getMember(String className, String memberName) {
    return _getClassIndex(className).getMember(memberName);
  }

  Member tryGetMember(String className, String memberName) {
    return classes[className]?.tryGetMember(memberName);
  }
}

class _MemberTable {
  final _ClassTable parent;
  final Class class_; // Null for top-level or extension.
  final Extension extension_; // Null for top-level or class.
  Map<String, Member> _members;

  Library get library => parent.library;

  _MemberTable.fromClass(this.parent, this.class_) : extension_ = null;
  _MemberTable.fromExtension(this.parent, this.extension_) : class_ = null;
  _MemberTable.topLevel(this.parent)
      : class_ = null,
        extension_ = null;

  Map<String, Member> get members {
    if (_members == null) {
      _members = <String, Member>{};
      if (class_ != null) {
        class_.procedures.forEach(addMember);
        class_.fields.forEach(addMember);
        class_.constructors.forEach(addMember);
      } else if (extension_ != null) {
        extension_.members.forEach(addExtensionMember);
      } else {
        library.procedures.forEach(addMember);
        library.fields.forEach(addMember);
      }
    }
    return _members;
  }

  String getDisambiguatedName(Member member) {
    if (member is Procedure) {
      if (member.isGetter) return LibraryIndex.getterPrefix + member.name.name;
      if (member.isSetter) return LibraryIndex.setterPrefix + member.name.name;
    }
    return member.name.name;
  }

  void addMember(Member member) {
    if (member.name.isPrivate && member.name.library != library) {
      // Members whose name is private to other libraries cannot currently
      // be found with the LibraryIndex class.
      return;
    }
    _members[getDisambiguatedName(member)] = member;
  }

  String getDisambiguatedExtensionName(
      ExtensionMemberDescriptor extensionMember) {
    if (extensionMember.kind == ExtensionMemberKind.TearOff)
      return LibraryIndex.tearoffPrefix + extensionMember.name.name;
    if (extensionMember.kind == ExtensionMemberKind.Getter)
      return LibraryIndex.getterPrefix + extensionMember.name.name;
    if (extensionMember.kind == ExtensionMemberKind.Setter)
      return LibraryIndex.setterPrefix + extensionMember.name.name;
    return extensionMember.name.name;
  }

  void addExtensionMember(ExtensionMemberDescriptor extensionMember) {
    final replacement = extensionMember.member.node;
    if (replacement is! Member) return;
    Member member = replacement;
    if (member.name.isPrivate && member.name.library != library) {
      // Members whose name is private to other libraries cannot currently
      // be found with the LibraryIndex class.
      return;
    }

    final name = getDisambiguatedExtensionName(extensionMember);
    _members[name] = replacement;
  }

  String get containerName {
    if (class_ != null) {
      return "class '${class_.name}' in ${parent.containerName}";
    } else if (extension_ != null) {
      return "extension '${extension_.name}' in ${parent.containerName}";
    } else {
      return "top-level of ${parent.containerName}";
    }
  }

  Member getMember(String name) {
    var member = members[name];
    if (member == null) {
      String message = "A member with disambiguated name '$name' was not found "
          "in $containerName";
      var getter = LibraryIndex.getterPrefix + name;
      var setter = LibraryIndex.setterPrefix + name;
      if (members[getter] != null || members[setter] != null) {
        throw "$message. Did you mean '$getter' or '$setter'?";
      }
      throw message;
    }
    return member;
  }

  Member tryGetMember(String name) => members[name];
}
