// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_CSSOM_SELECTOR_TREE_H_
#define COBALT_CSSOM_SELECTOR_TREE_H_

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/containers/small_map.h"
#include "base/hash_tables.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "cobalt/base/token.h"
#include "cobalt/cssom/combinator.h"
#include "cobalt/cssom/pseudo_class_type.h"
#include "cobalt/cssom/simple_selector_type.h"
#include "cobalt/cssom/specificity.h"

namespace cobalt {
namespace cssom {

class CompoundSelector;
class ComplexSelector;
class CSSStyleRule;

// A selector tree is a tree structure that organizes compound selectors. It is
// used to accelerate rule matching. More details can be found in the doc:
// https://docs.google.com/document/d/1LTbSenGsGR94JTGg6DfZDXYB3MBBCp4C8dRC4rckt_8/
class SelectorTree {
 public:
  typedef std::vector<base::WeakPtr<CSSStyleRule> > Rules;

  class Node;

  // This class can be used to store Nodes.  It stores the Nodes in its
  // internal buffer whose size can be configured via template parameter.
  // After the internal buffer is used up the extra Nodes will be stored inside
  // the contained std::vector.
  // TODO: Move this off to its own file if this can also be used by
  // other code.
  template <size_t InternalCacheSize>
  class NodeSet {
   public:
    // Minimum interface for iterator.
    class const_iterator {
     public:
      const_iterator(const NodeSet* set, size_t index)
          : set_(set), index_(index) {}
      void operator++() { ++index_; }
      const Node* operator*() const { return set_->GetNode(index_); }
      bool operator!=(const const_iterator& that) const {
        return set_ != that.set_ || index_ != that.index_;
      }

     private:
      const NodeSet* set_;
      size_t index_;
    };

    NodeSet() : size_(0) {}
    void insert(const Node* node, bool check_for_duplicate = false) {
      // If |check_for_duplicate| is true, then check if the node is already
      // contained. In nearly all cases, this check is unnecessary because it is
      // already known that the node is not a duplicate. As a result, the caller
      // must explicitly request the check when needed.
      if (check_for_duplicate) {
        for (size_t i = 0; i < size_; ++i) {
          if (GetNode(i) == node) {
            return;
          }
        }
      }

      if (size_ < InternalCacheSize) {
        nodes_[size_] = node;
      } else {
        nodes_vector_.push_back(node);
      }
      ++size_;
    }
    template <class ConstIterator>
    void insert(ConstIterator begin, ConstIterator end,
                bool check_for_duplicate = false) {
      while (begin != end) {
        insert(*begin, check_for_duplicate);
        ++begin;
      }
    }

    const_iterator begin() const { return const_iterator(this, 0); }
    const_iterator end() const { return const_iterator(this, size_); }
    size_t size() const { return size_; }
    void clear() {
      size_ = 0;
      nodes_vector_.clear();
    }
    const Node* GetNode(size_t index) const {
      if (index < InternalCacheSize) {
        return nodes_[index];
      }
      return nodes_vector_[index - InternalCacheSize];
    }

   private:
    size_t size_;
    const Node* nodes_[InternalCacheSize];
    std::vector<const Node*> nodes_vector_;
  };

  struct CompoundNodeLessThan {
    bool operator()(const CompoundSelector* lhs,
                    const CompoundSelector* rhs) const;
  };

  // This class holds references to Nodes allocated on the heap that are owned
  // by the same parent Node.  It deletes all contained Nodes on destruction.
  class OwnedNodes
      : public base::SmallMap<
            std::map<CompoundSelector*, Node*, CompoundNodeLessThan>, 2> {
   public:
    ~OwnedNodes() {
      for (iterator iter = begin(); iter != end(); ++iter) {
        delete iter->second;
      }
    }
  };

  struct PseudoClassNode {
    PseudoClassType pseudo_class_type;
    CombinatorType combinator_type;
    Node* node;
  };

  struct SimpleSelectorNode {
    SimpleSelectorType simple_selector_type;
    CombinatorType combinator_type;
    Node* node;
  };

  typedef std::vector<SimpleSelectorNode> SimpleSelectorNodes;
  typedef std::vector<PseudoClassNode> PseudoClassNodes;
  // The vast majority of SelectorTextToNodesMap objects have 4 or fewer
  // selectors. However, they occasionally can number in the hundreds. Using
  // a SmallMap with an array size of 4, allows both cases to be handled
  // quickly.
  typedef base::SmallMap<base::hash_map<base::Token, SimpleSelectorNodes>, 4>
      SelectorTextToNodesMap;

  class Node {
   public:
    CompoundSelector* compound_selector() const { return compound_selector_; }
    Specificity cumulative_specificity() const {
      return cumulative_specificity_;
    }
    bool HasCombinator(CombinatorType type) const {
      return (combinator_mask_ & (1 << type)) != 0;
    }
    Rules& rules() { return rules_; }
    const Rules& rules() const { return rules_; }

    const PseudoClassNodes& pseudo_class_nodes() const {
      return pseudo_class_nodes_;
    }
    bool HasAnyPseudoClass() const { return pseudo_class_mask_ != 0; }
    bool HasPseudoClass(PseudoClassType pseudo_class_type,
                        CombinatorType combinator_type) const {
      return (pseudo_class_mask_ &
              (1u << (pseudo_class_type * kCombinatorCount +
                      combinator_type))) != 0;
    }
    void AppendPseudoClassNode(PseudoClassType pseudo_class_type,
                               CombinatorType combinator_type, Node* node) {
      PseudoClassNode child_node = {pseudo_class_type, combinator_type, node};
      pseudo_class_nodes_.push_back(child_node);
      pseudo_class_mask_ |=
          (1u << (pseudo_class_type * kCombinatorCount + combinator_type));
    }

    const SelectorTextToNodesMap* selector_nodes_map() const {
      return selector_nodes_map_.get();
    }
    bool HasSimpleSelector(SimpleSelectorType simple_selector_type,
                           CombinatorType combinator_type) const {
      return (selector_mask_ & (1u << (simple_selector_type * kCombinatorCount +
                                       combinator_type))) != 0;
    }
    void AppendSimpleSelector(base::Token name,
                              SimpleSelectorType simple_selector_type,
                              CombinatorType combinator_type, Node* node) {
      // Create the SelectorTextToNodesMap if this is the first simple selector
      // being appended.
      if (!selector_nodes_map_) {
        selector_nodes_map_.reset(new SelectorTextToNodesMap());
      }

      SimpleSelectorNode child_node = {simple_selector_type, combinator_type,
                                       node};
      (*selector_nodes_map_)[name].push_back(child_node);
      selector_mask_ |=
          (1u << (simple_selector_type * kCombinatorCount + combinator_type));
    }

   private:
    friend class SelectorTree;

    Node();
    Node(CompoundSelector* compound_selector, Specificity parent_specificity);

    // Bit mask used to quickly reject a certain combinator type.
    uint8 combinator_mask_;
    COMPILE_ASSERT(sizeof(uint8) * 8 >= kCombinatorCount,
                   combinator_mask_does_not_have_enough_bits);

    // Pointer to one of the equivalent compound selectors.
    CompoundSelector* compound_selector_;
    // Sum of specificity from root to this node.
    Specificity cumulative_specificity_;

    // Indexes for the children. This is a scoped_ptr because the majority of
    // nodes do not contain any children.
    scoped_ptr<SelectorTextToNodesMap> selector_nodes_map_;
    // Bit mask used to quickly reject a certain selector type and combinator
    // combination.
    uint32 selector_mask_;
    COMPILE_ASSERT(sizeof(uint32) * 8 >=
                       kSimpleSelectorTypeCount * kCombinatorCount,
                   selector_mask_does_not_have_enough_bits);
    PseudoClassNodes pseudo_class_nodes_;
    // Bit mask used to quickly reject a certain pseudo class and combinator
    // combination.
    uint32 pseudo_class_mask_;
    COMPILE_ASSERT(sizeof(uint32) * 8 >=
                       kPseudoClassTypeCount * kCombinatorCount,
                   pseudo_class_mask_does_not_have_enough_bits);

    // Rules that end with this node.
    Rules rules_;
  };

  SelectorTree() : has_sibling_combinators_(false) { root_set_.insert(&root_); }

  const Node* root() const { return &root_; }
  const NodeSet<1>& root_set() const { return root_set_; }

  bool has_sibling_combinators() const { return has_sibling_combinators_; }

  void AppendRule(CSSStyleRule* rule);
  void RemoveRule(CSSStyleRule* rule);

  // Used by unit tests only.
  const OwnedNodes& children(const Node* node, CombinatorType combinator);

 private:
  // Gets or creates node for complex selector, starting from root.
  Node* GetOrCreateNodeForComplexSelector(ComplexSelector* selector);

  // Gets or creates node for compound selector, starting from given node, using
  // given combiantor as edge.
  Node* GetOrCreateNodeForCompoundSelector(CompoundSelector* compound_selector,
                                           Node* parent_node,
                                           CombinatorType combinator);

  Node root_;
  NodeSet<1> root_set_;

  // This variable maps from a parent Node and a combinator type to child Nodes
  // under the particular parent Node corresponding to the particular combinator
  // type.  It is only used when modifying the SelectorTree and is not used
  // during rule matching.  So we store it externally to the Node to minimize
  // the size of Node structure.
  std::map<std::pair<const Node*, CombinatorType>, OwnedNodes> owned_nodes_map_;

  bool has_sibling_combinators_;

  DISALLOW_COPY_AND_ASSIGN(SelectorTree);
};

}  // namespace cssom
}  // namespace cobalt

#endif  // COBALT_CSSOM_SELECTOR_TREE_H_
