// Copyright (c) 2018, 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.

part of 'serialization.dart';

/// Helper for looking up object library data from an [ir.Component] node.
class ComponentLookup {
  final ir.Component _component;

  /// Cache of [_LibraryData] for libraries in [_component].
  Map<Uri, _LibraryData> _libraryMap;

  ComponentLookup(this._component);

  /// Returns the [_LibraryData] object for the library with the [canonicalUri].
  _LibraryData getLibraryDataByUri(Uri canonicalUri) {
    if (_libraryMap == null) {
      _libraryMap = {};
      for (ir.Library library in _component.libraries) {
        _libraryMap[library.importUri] = new _LibraryData(library);
      }
    }
    return _libraryMap[canonicalUri];
  }
}

/// Returns a name uniquely identifying a member within its enclosing library
/// or class.
String _computeMemberName(ir.Member member) {
  if (member.name.isPrivate &&
      member.name.libraryName != member.enclosingLibrary.reference) {
    // TODO(33732): Handle noSuchMethod forwarders for private members from
    // other libraries.
    return null;
  }
  String name = member.name.name;
  if (member is ir.Procedure && member.kind == ir.ProcedureKind.Setter) {
    name += "=";
  }
  return name;
}

/// Helper for looking up classes and members from an [ir.Library] node.
class _LibraryData {
  /// The [ir.Library] that defines the library.
  final ir.Library node;

  /// Cache of [_ClassData] for classes in this library.
  Map<String, _ClassData> _classes;

  /// Cache of [_MemberData] for members in this library.
  Map<String, _MemberData> _members;

  _LibraryData(this.node);

  /// Returns the [_ClassData] for the class [name] in this library.
  _ClassData lookupClass(String name) {
    if (_classes == null) {
      _classes = {};
      for (ir.Class cls in node.classes) {
        assert(!_classes.containsKey(cls.name),
            "Duplicate class '${cls.name}' in $_classes trying to add $cls.");
        _classes[cls.name] = new _ClassData(cls);
      }
    }
    return _classes[name];
  }

  /// Returns the [_MemberData] for the member uniquely identified by [name] in
  /// this library.
  _MemberData lookupMember(String name) {
    if (_members == null) {
      _members = {};
      for (ir.Member member in node.members) {
        String name = _computeMemberName(member);
        if (name == null) continue;
        assert(!_members.containsKey(name),
            "Duplicate member '$name' in $_members trying to add $member.");
        _members[name] = new _MemberData(member);
      }
    }
    return _members[name];
  }

  String toString() => '_LibraryData($node(${identityHashCode(node)}))';
}

/// Helper for looking up members from an [ir.Class] node.
class _ClassData {
  /// The [ir.Class] that defines the class.
  final ir.Class node;

  /// Cache of [_MemberData] for members in this class.
  Map<String, _MemberData> _members;

  _ClassData(this.node);

  /// Returns the [_MemberData] for the member uniquely identified by [name] in
  /// this class.
  _MemberData lookupMember(String name) {
    if (_members == null) {
      _members = {};
      for (ir.Member member in node.members) {
        String name = _computeMemberName(member);
        if (name == null) continue;
        assert(!_members.containsKey(name),
            "Duplicate member '$name' in $_members trying to add $member.");
        _members[name] = new _MemberData(member);
      }
    }
    return _members[name];
  }

  String toString() => '_ClassData($node(${identityHashCode(node)}))';
}

/// Helper for looking up child [ir.TreeNode]s of a [ir.Member] node.
class _MemberData {
  /// The [ir.Member] that defines the member.
  final ir.Member node;

  /// Cached index to [ir.TreeNode] map used for deserialization of
  /// [ir.TreeNode]s.
  Map<int, ir.TreeNode> _indexToNodeMap;

  /// Cached [ir.TreeNode] to index map used for serialization of
  /// [ir.TreeNode]s.
  Map<ir.TreeNode, int> _nodeToIndexMap;

  _MemberData(this.node);

  void _ensureMaps() {
    if (_indexToNodeMap == null) {
      _indexToNodeMap = {};
      _nodeToIndexMap = {};
      node.accept(
          new _TreeNodeIndexerVisitor(_indexToNodeMap, _nodeToIndexMap));
    }
  }

  /// Returns the [ir.TreeNode] corresponding to [index] in this member.
  ir.TreeNode getTreeNodeByIndex(int index) {
    _ensureMaps();
    ir.TreeNode treeNode = _indexToNodeMap[index];
    assert(treeNode != null, "No TreeNode found for index $index in $node.");
    return treeNode;
  }

  /// Returns the index corresponding to [ir.TreeNode] in this member.
  int getIndexByTreeNode(ir.TreeNode node) {
    _ensureMaps();
    int index = _nodeToIndexMap[node];
    assert(index != null, "No index found for ${node.runtimeType}.");
    return index;
  }

  String toString() => '_MemberData($node(${identityHashCode(node)}))';
}
