// Copyright (c) 2012, 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 universe;

class SelectorMap<T> extends PartialTypeTree {

  SelectorMap(Compiler compiler) : super(compiler);

  SelectorMapNode<T> newSpecializedNode(ClassElement type)
      => new SelectorMapNode<T>(type);

  T operator [](Selector selector) {
    SelectorMapNode<T> node = findNode(selectorType(selector), false);
    if (node == null) return null;
    Link<SelectorValue<T>> selectors = node.selectorsByName[selector.name];
    if (selectors == null) return null;
    for (Link link = selectors; !link.isEmpty; link = link.tail) {
      SelectorValue<T> existing = link.head;
      if (existing.selector.equalsUntyped(selector)) return existing.value;
    }
    return null;
  }

  void operator []=(Selector selector, T value) {
    SelectorMapNode<T> node = findNode(selectorType(selector), true);
    Link<SelectorValue<T>> selectors = node.selectorsByName[selector.name];
    if (selectors == null) {
      // No existing selectors with the given name. Create a new
      // linked list.
      SelectorValue<T> head = new SelectorValue<T>(selector, value);
      node.selectorsByName[selector.name] =
          new Link<SelectorValue<T>>().prepend(head);
    } else {
      // Run through the linked list of selectors with the same name. If
      // we find one that matches, we update the value in the mapping.
      for (Link link = selectors; !link.isEmpty; link = link.tail) {
        SelectorValue<T> existing = link.head;
        // It is safe to ignore the type here, because all selector
        // mappings that are stored in a single node have the same type.
        if (existing.selector.equalsUntyped(selector)) {
          existing.value = value;
          return;
        }
      }
      // We could not find an existing mapping for the selector, so
      // we add a new one to the existing linked list.
      SelectorValue<T> head = new SelectorValue<T>(selector, value);
      node.selectorsByName[selector.name] = selectors.prepend(head);
    }
  }

  // TODO(kasperl): Share code with the [] operator?
  bool containsKey(Selector selector) {
    SelectorMapNode<T> node = findNode(selectorType(selector), false);
    if (node == null) return false;
    Link<SelectorValue<T>> selectors = node.selectorsByName[selector.name];
    if (selectors == null) return false;
    for (Link link = selectors; !link.isEmpty; link = link.tail) {
      SelectorValue<T> existing = link.head;
      if (existing.selector.equalsUntyped(selector)) return true;
    }
    return false;
  }

  /**
   * Visits all mappings for selectors that may be used to invoke the
   * given [member] element. If the [visit] function ever returns false,
   * we abort the traversal early.
   */
  void visitMatching(Element member, bool visit(Selector selector, T value)) {
    assert(member.isMember());
    if (root == null) return;
    // TODO(kasperl): For now, we use a different implementation for
    // visiting if the tree contains interface subtypes.
    if (containsInterfaceSubtypes) {
      visitAllMatching(member, visit);
    } else {
      visitHierarchyMatching(member, visit);
    }
  }

  void visitAllMatching(Element member, bool visit(selector, value)) {
    root.visitRecursively((SelectorMapNode<T> node) {
      Link<SelectorValue<T>> selectors = node.selectorsByName[member.name];
      if (selectors == null) return true;
      for (Link link = selectors; !link.isEmpty; link = link.tail) {
        SelectorValue<T> existing = link.head;
        Selector selector = existing.selector;
        // Since we're running through the entire tree we have to use
        // the applies method that takes types into account.
        if (selector.applies(member, compiler)) {
          if (!visit(selector, existing.value)) return false;
        }
      }
      return true;
    });
  }

  void visitHierarchyMatching(Element member, bool visit(selector, value)) {
    visitHierarchy(member.getEnclosingClass(), (SelectorMapNode<T> node) {
      Link<SelectorValue<T>> selectors = node.selectorsByName[member.name];
      if (selectors == null) return true;
      for (Link link = selectors; !link.isEmpty; link = link.tail) {
        SelectorValue<T> existing = link.head;
        Selector selector = existing.selector;
        if (selector.appliesUntyped(member, compiler)) {
          if (!visit(selector, existing.value)) return false;
        }
      }
      return true;
    });
  }

}

class SelectorMapNode<T> extends PartialTypeTreeNode {

  final Map<SourceString, Link<SelectorValue<T>>> selectorsByName;

  SelectorMapNode(ClassElement type) : super(type),
      selectorsByName = new Map<SourceString, Link<SelectorValue<T>>>();

}

class SelectorValue<T> {
  final Selector selector;
  T value;
  SelectorValue(this.selector, this.value);
  toString() => "$selector -> $value";
}
