// Copyright 2015 The Cobalt Authors. 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.

#include "cobalt/dom/rule_matching.h"

#include <algorithm>
#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/unused.h"
#include "cobalt/cssom/after_pseudo_element.h"
#include "cobalt/cssom/attribute_selector.h"
#include "cobalt/cssom/before_pseudo_element.h"
#include "cobalt/cssom/cascade_precedence.h"
#include "cobalt/cssom/child_combinator.h"
#include "cobalt/cssom/class_selector.h"
#include "cobalt/cssom/combinator.h"
#include "cobalt/cssom/combinator_visitor.h"
#include "cobalt/cssom/complex_selector.h"
#include "cobalt/cssom/compound_selector.h"
#include "cobalt/cssom/css_style_rule.h"
#include "cobalt/cssom/css_style_sheet.h"
#include "cobalt/cssom/descendant_combinator.h"
#include "cobalt/cssom/empty_pseudo_class.h"
#include "cobalt/cssom/following_sibling_combinator.h"
#include "cobalt/cssom/id_selector.h"
#include "cobalt/cssom/next_sibling_combinator.h"
#include "cobalt/cssom/not_pseudo_class.h"
#include "cobalt/cssom/property_value.h"
#include "cobalt/cssom/pseudo_element.h"
#include "cobalt/cssom/selector_tree.h"
#include "cobalt/cssom/selector_visitor.h"
#include "cobalt/cssom/simple_selector.h"
#include "cobalt/cssom/type_selector.h"
#include "cobalt/cssom/universal_selector.h"
#include "cobalt/dom/attr.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/dom_token_list.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/html_element.h"
#include "cobalt/dom/html_html_element.h"
#include "cobalt/dom/named_node_map.h"
#include "cobalt/dom/node_descendants_iterator.h"
#include "cobalt/dom/node_list.h"
#include "cobalt/dom/pseudo_element.h"
#include "cobalt/math/safe_integer_conversions.h"

namespace cobalt {
namespace dom {
namespace {

using cssom::SelectorTree;

struct NodeCombinatorType {
  NodeCombinatorType(const SelectorTree::Node* node,
                     cssom::CombinatorType combinator_type)
      : node(node), combinator_type(combinator_type) {}

  const SelectorTree::Node* node;
  cssom::CombinatorType combinator_type;
};

//////////////////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////////////////

// Matches an element against a selector. If the element doesn't match, returns
// NULL, otherwise returns the result of advancing the pointer to the element
// according to the combinators.
Element* MatchSelectorAndElement(cssom::Selector* selector, Element* element,
                                 bool matching_combinators);

//////////////////////////////////////////////////////////////////////////
// Combinator matcher
//////////////////////////////////////////////////////////////////////////

class CombinatorMatcher : public cssom::CombinatorVisitor {
 public:
  explicit CombinatorMatcher(Element* element) : element_(element) {
    DCHECK(element);
  }

  // Child combinator describes a childhood relationship between two elements.
  //   https://www.w3.org/TR/selectors4/#child-combinators
  void VisitChildCombinator(cssom::ChildCombinator* child_combinator) override {
    element_ = MatchSelectorAndElement(child_combinator->left_selector(),
                                       element_->parent_element(), true);
  }

  // Next-sibling combinator describes that the elements represented by the two
  // compound selectors share the same parent in the document tree and the
  // element represented by the first compound selector immediately precedes the
  // element represented by the second one.
  //   https://www.w3.org/TR/selectors4/#adjacent-sibling-combinators
  void VisitNextSiblingCombinator(
      cssom::NextSiblingCombinator* next_sibling_combinator) override {
    element_ =
        MatchSelectorAndElement(next_sibling_combinator->left_selector(),
                                element_->previous_element_sibling(), true);
  }

  // Descendant combinator describes an element that is the descendant of
  // another element in the document tree.
  //   https://www.w3.org/TR/selectors4/#descendant-combinators
  void VisitDescendantCombinator(
      cssom::DescendantCombinator* descendant_combinator) override {
    do {
      element_ = element_->parent_element();
      Element* element = MatchSelectorAndElement(
          descendant_combinator->left_selector(), element_, true);
      if (element) {
        element_ = element;
        return;
      }
    } while (element_);
  }

  // Following-sibling combinator describes that the elements represented by the
  // two compound selectors share the same parent in the document tree and the
  // element represented by the first compound selector precedes (not
  // necessarily immediately) the element represented by the second one.
  //   https://www.w3.org/TR/selectors4/#general-sibling-combinators
  void VisitFollowingSiblingCombinator(
      cssom::FollowingSiblingCombinator* following_sibling_combinator)
      override {
    do {
      element_ = element_->previous_element_sibling();
      Element* element = MatchSelectorAndElement(
          following_sibling_combinator->left_selector(), element_, true);
      if (element) {
        element_ = element;
        return;
      }
    } while (element_);
  }

  Element* element() { return element_; }

 private:
  Element* element_;
  DISALLOW_COPY_AND_ASSIGN(CombinatorMatcher);
};

//////////////////////////////////////////////////////////////////////////
// Selector matcher
//////////////////////////////////////////////////////////////////////////

class SelectorMatcher : public cssom::SelectorVisitor {
 public:
  explicit SelectorMatcher(Element* element)
      : element_(element), matching_combinators_(false) {
    DCHECK(element);
  }
  SelectorMatcher(Element* element, bool matching_combinators)
      : element_(element), matching_combinators_(matching_combinators) {
    DCHECK(element);
  }

  // The universal selector represents the qualified name of any element type.
  //   https://www.w3.org/TR/selectors4/#universal-selector
  void VisitUniversalSelector(
      cssom::UniversalSelector* universal_selector) override {}

  // A type selector represents an instance of the element type in the document
  // tree.
  //   https://www.w3.org/TR/selectors4/#type-selector
  void VisitTypeSelector(cssom::TypeSelector* type_selector) override {
    if (type_selector->element_name() != element_->local_name()) {
      element_ = NULL;
    }
  }

  // An attribute selector represents an element that has an attribute that
  // matches the attribute represented by the attribute selector.
  //   https://www.w3.org/TR/selectors4/#attribute-selector
  void VisitAttributeSelector(
      cssom::AttributeSelector* attribute_selector) override {
    if (!element_->HasAttribute(attribute_selector->attribute_name().c_str())) {
      element_ = NULL;
      return;
    }

    switch (attribute_selector->value_match_type()) {
      case cssom::AttributeSelector::kNoMatch:
        return;
      case cssom::AttributeSelector::kEquals:
        if (element_->GetAttribute(attribute_selector->attribute_name().c_str())
                .value() != attribute_selector->attribute_value()) {
          element_ = NULL;
        }
        return;
      case cssom::AttributeSelector::kIncludes:
      case cssom::AttributeSelector::kDashMatch:
      case cssom::AttributeSelector::kBeginsWith:
      case cssom::AttributeSelector::kEndsWith:
      case cssom::AttributeSelector::kContains:
        NOTIMPLEMENTED();
        element_ = NULL;
        return;
    }
  }

  // The class selector represents an element belonging to the class identified
  // by the identifier.
  //   https://www.w3.org/TR/selectors4/#class-selector
  void VisitClassSelector(cssom::ClassSelector* class_selector) override {
    if (!element_->class_list()->ContainsValid(class_selector->class_name())) {
      element_ = NULL;
    }
  }

  // An ID selector represents an element instance that has an identifier that
  // matches the identifier in the ID selector.
  //   https://www.w3.org/TR/selectors4/#id-selector
  void VisitIdSelector(cssom::IdSelector* id_selector) override {
    if (id_selector->id() != element_->id()) {
      element_ = NULL;
    }
  }

  // The :active pseudo-class applies while an element is being activated by the
  // user. For example, between the times the user presses the mouse button and
  // releases it. On systems with more than one mouse button, :active applies
  // only to the primary or primary activation button (typically the "left"
  // mouse button), and any aliases thereof.
  //   https://www.w3.org/TR/selectors4/#active-pseudo
  void VisitActivePseudoClass(cssom::ActivePseudoClass*) override {
    NOTIMPLEMENTED();
    element_ = NULL;
  }

  // The :empty pseudo-class represents an element that has no content children.
  //   https://www.w3.org/TR/selectors4/#empty-pseudo
  void VisitEmptyPseudoClass(cssom::EmptyPseudoClass*) override {
    if (!element_->IsEmpty()) {
      element_ = NULL;
    }
  }

  // The :focus pseudo-class applies while an element has the focus (accepts
  // keyboard or mouse events, or other forms of input).
  //   https://www.w3.org/TR/selectors4/#focus-pseudo
  void VisitFocusPseudoClass(cssom::FocusPseudoClass*) override {
    if (!element_->HasFocus()) {
      element_ = NULL;
    }
  }

  // The :hover pseudo-class applies while the user designates an element with a
  // pointing device, but does not necessarily activate it. For example, a
  // visual user agent could apply this pseudo-class when the cursor (mouse
  // pointer) hovers over a box generated by the element. Interactive user
  // agents that cannot detect hovering due to hardware limitations (e.g., a pen
  // device that does not detect hovering) are still conforming.
  //   https://www.w3.org/TR/selectors4/#hover-pseudo
  void VisitHoverPseudoClass(cssom::HoverPseudoClass*) override {
    if (!element_->AsHTMLElement() ||
        !element_->AsHTMLElement()->IsDesignated()) {
      element_ = NULL;
    }
  }

  // The negation pseudo-class, :not(), is a functional pseudo-class taking a
  // selector list as an argument. It represents an element that is not
  // represented by its argument.
  //   https://www.w3.org/TR/selectors4/#negation-pseudo
  void VisitNotPseudoClass(cssom::NotPseudoClass* not_pseudo_class) override {
    if (MatchSelectorAndElement(not_pseudo_class->selector(), element_, true)) {
      element_ = NULL;
    }
  }

  // Pseudo elements doesn't affect whether the selector matches or not.

  // The :after pseudo-element represents a generated element.
  //   https://www.w3.org/TR/CSS21/generate.html#before-after-content
  void VisitAfterPseudoElement(cssom::AfterPseudoElement*) override {}

  // The :before pseudo-element represents a generated element.
  //   https://www.w3.org/TR/CSS21/generate.html#before-after-content
  void VisitBeforePseudoElement(cssom::BeforePseudoElement*) override {}

  // A compound selector is a chain of simple selectors that are not separated
  // by a combinator.
  //   https://www.w3.org/TR/selectors4/#compound
  void VisitCompoundSelector(
      cssom::CompoundSelector* compound_selector) override {
    DCHECK_GT(compound_selector->simple_selectors().size(), 0U);

    // Iterate through all the simple selectors. If any of the simple selectors
    // doesn't match, the compound selector doesn't match.
    for (cssom::CompoundSelector::SimpleSelectors::const_iterator
             selector_iterator = compound_selector->simple_selectors().begin();
         selector_iterator != compound_selector->simple_selectors().end();
         ++selector_iterator) {
      element_ =
          MatchSelectorAndElement(selector_iterator->get(), element_, false);
      if (!element_) {
        return;
      }
    }

    // Check combinator.
    if (matching_combinators_ && compound_selector->left_combinator()) {
      CombinatorMatcher combinator_matcher(element_);
      compound_selector->left_combinator()->Accept(&combinator_matcher);
      element_ = combinator_matcher.element();
    }
  }

  // A complex selector is a chain of one or more compound selectors separated
  // by combinators.
  //   https://www.w3.org/TR/selectors4/#complex
  void VisitComplexSelector(cssom::ComplexSelector* complex_selector) override {
    element_ = MatchSelectorAndElement(complex_selector->last_selector(),
                                       element_, true);
  }

  Element* element() const { return element_; }

 private:
  Element* element_;
  bool matching_combinators_;
  DISALLOW_COPY_AND_ASSIGN(SelectorMatcher);
};

//////////////////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////////////////

Element* MatchSelectorAndElement(cssom::Selector* selector, Element* element,
                                 bool matching_combinators) {
  DCHECK(selector);
  if (!element) {
    return NULL;
  }

  SelectorMatcher selector_matcher(element, matching_combinators);
  selector->Accept(&selector_matcher);
  return selector_matcher.element();
}

void GatherCandidateNodesFromSelectorNodesMap(
    cssom::SimpleSelectorType simple_selector_type,
    cssom::CombinatorType combinator_type,
    const SelectorTree::Node* parent_node,
    const SelectorTree::SelectorTextToNodesMap* map, base::Token key,
    SelectorTree::NodePairs* candidate_nodes) {
  SelectorTree::SelectorTextToNodesMap::const_iterator it = map->find(key);
  if (it != map->end()) {
    const SelectorTree::SimpleSelectorNodes& nodes = it->second;
    for (const auto& nodes_iterator : nodes) {
      if (nodes_iterator.simple_selector_type == simple_selector_type &&
          nodes_iterator.combinator_type == combinator_type) {
        candidate_nodes->emplace_back(parent_node, nodes_iterator.node);
      }
    }
  }
}

void GatherCandidateNodesFromPseudoClassNodes(
    cssom::PseudoClassType pseudo_class_type,
    cssom::CombinatorType combinator_type,
    const SelectorTree::Node* parent_node,
    const SelectorTree::PseudoClassNodes& pseudo_class_nodes,
    SelectorTree::NodePairs* candidate_nodes) {
  for (const auto& nodes_iterator : pseudo_class_nodes) {
    if (nodes_iterator.pseudo_class_type == pseudo_class_type &&
        nodes_iterator.combinator_type == combinator_type) {
      candidate_nodes->emplace_back(parent_node, nodes_iterator.node);
    }
  }
}

bool GatherNodeModificationsAndUpdateTargetNodes(
    const SelectorTree::Nodes& source_nodes, SelectorTree::Nodes* target_nodes,
    SelectorTree::Nodes* added_nodes, SelectorTree::Nodes* removed_nodes) {
  if (source_nodes == *target_nodes) {
    return false;
  }

  added_nodes->clear();
  removed_nodes->clear();

  if (target_nodes->empty()) {
    // If the previous state of the nodes (|target_nodes|) is empty, then all
    // nodes in the new state (|source_nodes|) are being added.
    *added_nodes = source_nodes;
  } else if (source_nodes.empty()) {
    // If the new state (|source_nodes|) is empty, then all nodes in the
    // previous state (|target_nodes|) are being removed.
    *removed_nodes = *target_nodes;
  } else {
    // If neither the previous state nor the new state or empty, then the lists
    // must be manually searched to determine what is being added and removed.
    // Remove all nodes in |source_nodes| from |target_nodes|. Any of the nodes
    // that are not found in |target_nodes| are newly added nodes.
    size_t start_index = 0;
    for (const auto& check_node : source_nodes) {
      bool node_found = false;
      for (size_t index = start_index; index < target_nodes->size(); ++index) {
        if ((*target_nodes)[index] == check_node) {
          if (index == start_index) {
            ++start_index;
          }
          node_found = true;
          (*target_nodes)[index] = NULL;
          break;
        }
      }
      if (!node_found) {
        added_nodes->push_back(check_node);
      }
    }
    // Find nodes that remain in |target_nodes|. These did not exist in
    // |source_nodes| and are newly removed nodes.
    for (const auto& check_node : *target_nodes) {
      if (check_node != NULL) {
        removed_nodes->push_back(check_node);
      }
    }
  }

  *target_nodes = source_nodes;

  // Return whether or not any modifications were found.
  return !added_nodes->empty() || !removed_nodes->empty();
}

// Returns true if a matching node was added.
bool GatherMatchingNodes(const SelectorTree::Nodes& nodes,
                         cssom::CombinatorType combinator_type,
                         HTMLElement* element,
                         SelectorTree::NodePairs* scratchpad_node_pairs) {
  bool matching_node_added = false;

  // Gathering Phase: Generate candidate nodes from the nodes.
  SelectorTree::NodePairs* candidate_node_pairs = scratchpad_node_pairs;
  candidate_node_pairs->clear();

  const std::vector<base::Token>& element_class_list =
      element->class_list()->GetTokens();

  // Don't retrieve the element's attributes until they are needed. Retrieving
  // them typically requires the creation of a NamedNodeMap.
  scoped_refptr<NamedNodeMap> element_attributes;

  // Iterate through all nodes.
  for (const auto& node : nodes) {
    if (!node->HasCombinator(combinator_type)) {
      continue;
    }

    // Gather candidate nodes in node's children under the given combinator.
    const SelectorTree::SelectorTextToNodesMap* selector_nodes_map =
        node->selector_nodes_map();
    if (selector_nodes_map) {
      // Universal selector.
      if (node->HasSimpleSelector(cssom::kUniversalSelector, combinator_type)) {
        GatherCandidateNodesFromSelectorNodesMap(
            cssom::kUniversalSelector, combinator_type, node,
            selector_nodes_map, base::Token(), candidate_node_pairs);
      }

      // Type selector.
      if (node->HasSimpleSelector(cssom::kTypeSelector, combinator_type)) {
        GatherCandidateNodesFromSelectorNodesMap(
            cssom::kTypeSelector, combinator_type, node, selector_nodes_map,
            element->local_name(), candidate_node_pairs);
      }

      // Attribute selector.
      if (node->HasSimpleSelector(cssom::kAttributeSelector, combinator_type)) {
        // If the element's attributes have not been retrieved yet, then
        // retrieve them now.
        if (!element_attributes) {
          element_attributes = element->attributes();
        }

        for (unsigned int index = 0; index < element_attributes->length();
             ++index) {
          GatherCandidateNodesFromSelectorNodesMap(
              cssom::kAttributeSelector, combinator_type, node,
              selector_nodes_map,
              base::Token(element_attributes->Item(index)->name()),
              candidate_node_pairs);
        }
      }

      // Class selector.
      if (node->HasSimpleSelector(cssom::kClassSelector, combinator_type)) {
        for (const auto& element_class : element_class_list) {
          GatherCandidateNodesFromSelectorNodesMap(
              cssom::kClassSelector, combinator_type, node, selector_nodes_map,
              element_class, candidate_node_pairs);
        }
      }

      // Id selector.
      if (node->HasSimpleSelector(cssom::kIdSelector, combinator_type)) {
        GatherCandidateNodesFromSelectorNodesMap(
            cssom::kIdSelector, combinator_type, node, selector_nodes_map,
            element->id(), candidate_node_pairs);
      }
    }

    // Only check for specific pseudo classes when the node has as least one.
    if (node->HasAnyPseudoClass()) {
      // Empty pseudo class.
      if (node->HasPseudoClass(cssom::kEmptyPseudoClass, combinator_type) &&
          element->IsEmpty()) {
        GatherCandidateNodesFromPseudoClassNodes(
            cssom::kEmptyPseudoClass, combinator_type, node,
            node->pseudo_class_nodes(), candidate_node_pairs);
      }

      // Focus pseudo class.
      if (node->HasPseudoClass(cssom::kFocusPseudoClass, combinator_type) &&
          element->HasFocus()) {
        GatherCandidateNodesFromPseudoClassNodes(
            cssom::kFocusPseudoClass, combinator_type, node,
            node->pseudo_class_nodes(), candidate_node_pairs);
      }

      // Hover pseudo class.
      if (node->HasPseudoClass(cssom::kHoverPseudoClass, combinator_type) &&
          element->IsDesignated()) {
        GatherCandidateNodesFromPseudoClassNodes(
            cssom::kHoverPseudoClass, combinator_type, node,
            node->pseudo_class_nodes(), candidate_node_pairs);
      }

      // Not pseudo class.
      if (node->HasPseudoClass(cssom::kNotPseudoClass, combinator_type)) {
        GatherCandidateNodesFromPseudoClassNodes(
            cssom::kNotPseudoClass, combinator_type, node,
            node->pseudo_class_nodes(), candidate_node_pairs);
      }
    }
  }

  // Verifying Phase: Check all candidate nodes and run callback for matching
  // nodes.
  for (const auto& candidate_node_pair : *candidate_node_pairs) {
    const SelectorTree::Node* candidate_node = candidate_node_pair.second;

    // Verify that this node is a match:
    // 1. If the candidate node's compound selector doesn't require a visit to
    //    verify the match, then the act of gathering the node as a candidate
    //    proved the match.
    // 2. Otherwise, the node requires additional verification checks, so call
    //    MatchSelectorAndElement().
    if (!candidate_node->compound_selector()
             ->requires_rule_matching_verification_visit() ||
        MatchSelectorAndElement(candidate_node->compound_selector(), element,
                                false)) {
      matching_node_added = true;
      element->rule_matching_state()->matching_nodes_parent_nodes.push_back(
          candidate_node_pair.first);
      element->rule_matching_state()->matching_nodes.push_back(candidate_node);
    }
  }

  return matching_node_added;
}

// Returns true if a matching node was removed.
bool RemoveNodesFromMatchingNodes(
    const SelectorTree::Nodes& parent_nodes_to_remove,
    SelectorTree::Nodes* parent_nodes, SelectorTree::Nodes* matching_nodes) {
  DCHECK_EQ(parent_nodes->size(), matching_nodes->size());
  bool node_removed = false;

  // Find any |parent_nodes| that are being removed. Remove these from both
  // |parent_nodes| and |matching_nodes|, as these two containers are kept in
  // sync.
  for (const auto& parent_node_to_remove : parent_nodes_to_remove) {
    for (size_t index = 0; index < parent_nodes->size();) {
      if (parent_node_to_remove == (*parent_nodes)[index]) {
        node_removed = true;
        parent_nodes->erase(parent_nodes->begin() + index);
        matching_nodes->erase(matching_nodes->begin() + index);
      } else {
        ++index;
      }
    }
  }

  return node_removed;
}

// Returns true if the matching nodes were modified.
bool UpdateMatchingNodesFromNodeModifications(
    const SelectorTree::Nodes& added_nodes,
    const SelectorTree::Nodes& removed_nodes,
    cssom::CombinatorType combinator_type, HTMLElement* element,
    SelectorTree::NodePairs* scratchpad_node_pairs) {
  // First gather the matching nodes found in |added_nodes|.
  bool matching_nodes_modified = GatherMatchingNodes(
      added_nodes, combinator_type, element, scratchpad_node_pairs);

  // Now remove any matching nodes found in |removed_nodes|.
  HTMLElement::RuleMatchingState* element_matching_state =
      element->rule_matching_state();
  matching_nodes_modified |= RemoveNodesFromMatchingNodes(
      removed_nodes, &element_matching_state->matching_nodes_parent_nodes,
      &element_matching_state->matching_nodes);

  return matching_nodes_modified;
}

void UpdateRuleMatchingStateCombinatorNodes(
    HTMLElement::RuleMatchingState* matching_state,
    cssom::CombinatorType combinator_type) {
  // Only descendant and following sibling combinators are supported.
  DCHECK(combinator_type == cssom::kDescendantCombinator ||
         combinator_type == cssom::kFollowingSiblingCombinator);
  if (!matching_state) {
    return;
  }

  DCHECK(matching_state->is_set);
  bool& is_dirty = combinator_type == cssom::kDescendantCombinator
                       ? matching_state->are_descendant_nodes_dirty
                       : matching_state->are_following_sibling_nodes_dirty;
  if (!is_dirty) {
    return;
  }

  const SelectorTree::Nodes& base_combinator_nodes =
      combinator_type == cssom::kDescendantCombinator
          ? matching_state->parent_descendant_nodes
          : matching_state->previous_sibling_following_sibling_nodes;
  SelectorTree::Nodes& combinator_nodes =
      combinator_type == cssom::kDescendantCombinator
          ? matching_state->descendant_nodes
          : matching_state->following_sibling_nodes;

  // First copy the base combinator nodes and then add any matching nodes that
  // have the required combinator and are not already included within the list.
  combinator_nodes = base_combinator_nodes;
  for (const auto& node : matching_state->matching_nodes) {
    if (node->HasCombinator(combinator_type) &&
        std::find(base_combinator_nodes.begin(), base_combinator_nodes.end(),
                  node) == base_combinator_nodes.end()) {
      combinator_nodes.push_back(node);
    }
  }

  is_dirty = false;
}

// Returns true if the matching state was modified.
bool UpdateElementRuleMatchingState(HTMLElement* element) {
  SelectorTree* selector_tree = element->node_document()->selector_tree();
  bool sibling_matching_active = selector_tree->has_sibling_combinators();

  // Retrieve the parent and previous sibling of the current element.
  HTMLElement* parent = element->parent_element()
                            ? element->parent_element()->AsHTMLElement()
                            : NULL;
  HTMLElement* previous_sibling =
      sibling_matching_active && element->previous_element_sibling()
          ? element->previous_element_sibling()->AsHTMLElement()
          : NULL;

  // Retrieve the rule matching state of this element, its parent, and its
  // previous sibling.
  HTMLElement::RuleMatchingState* element_matching_state =
      element->rule_matching_state();
  HTMLElement::RuleMatchingState* parent_matching_state =
      parent ? parent->rule_matching_state() : NULL;
  HTMLElement::RuleMatchingState* previous_sibling_matching_state =
      previous_sibling ? previous_sibling->rule_matching_state() : NULL;

  // A parent must always have valid matching rules when its child is being
  // updated.
  DCHECK(!parent || parent->matching_rules_valid());

  // Ensure that the previous sibling has updated matching rules. This is
  // necessary because Document::UpdateComputedStyleOnElementAndAncestor() does
  // not update previous siblings so it is possible for an element to have its
  // computed style updated while previous siblings have invalid matching rules.
  if (previous_sibling) {
    UpdateElementMatchingRules(previous_sibling);
    DCHECK(previous_sibling->matching_rules_valid());
  }

  // Ensure that the required combinator nodes of the parent and previous
  // sibling are up to date. These are lazily updated, so they won't be updated
  // until the first child/next sibling needs them.
  UpdateRuleMatchingStateCombinatorNodes(parent_matching_state,
                                         cssom::kDescendantCombinator);
  UpdateRuleMatchingStateCombinatorNodes(previous_sibling_matching_state,
                                         cssom::kFollowingSiblingCombinator);

  bool matching_nodes_modified = !element_matching_state->is_set;

  // Gather modifications between the element's previous state and current state
  // for each combinator type, and use them to update the element's matching
  // nodes.
  SelectorTree::Nodes* added_nodes = selector_tree->scratchpad_nodes_1();
  SelectorTree::Nodes* removed_nodes = selector_tree->scratchpad_nodes_2();

  // Child combinator
  if (parent_matching_state &&
      GatherNodeModificationsAndUpdateTargetNodes(
          parent_matching_state->matching_nodes,
          &element_matching_state->parent_matching_nodes, added_nodes,
          removed_nodes)) {
    matching_nodes_modified |= UpdateMatchingNodesFromNodeModifications(
        *added_nodes, *removed_nodes, cssom::kChildCombinator, element,
        selector_tree->scratchpad_node_pairs());
  }

  // Descendant combinator
  const SelectorTree::Nodes& parent_descendant_nodes =
      parent_matching_state ? parent_matching_state->descendant_nodes
                            : selector_tree->root_nodes();
  if (GatherNodeModificationsAndUpdateTargetNodes(
          parent_descendant_nodes,
          &element_matching_state->parent_descendant_nodes, added_nodes,
          removed_nodes)) {
    element_matching_state->are_descendant_nodes_dirty = true;
    matching_nodes_modified |= UpdateMatchingNodesFromNodeModifications(
        *added_nodes, *removed_nodes, cssom::kDescendantCombinator, element,
        selector_tree->scratchpad_node_pairs());
  }

  // Siblings only need to be checked if they're active.
  if (sibling_matching_active) {
    const SelectorTree::Nodes empty_nodes;

    // Next sibling combinator
    const SelectorTree::Nodes& previous_sibling_matching_nodes =
        previous_sibling_matching_state
            ? previous_sibling_matching_state->matching_nodes
            : empty_nodes;
    if (GatherNodeModificationsAndUpdateTargetNodes(
            previous_sibling_matching_nodes,
            &element_matching_state->previous_sibling_matching_nodes,
            added_nodes, removed_nodes)) {
      matching_nodes_modified |= UpdateMatchingNodesFromNodeModifications(
          *added_nodes, *removed_nodes, cssom::kNextSiblingCombinator, element,
          selector_tree->scratchpad_node_pairs());
    }

    // Following sibling combinator
    const SelectorTree::Nodes& previous_sibling_following_sibling_nodes =
        previous_sibling_matching_state
            ? previous_sibling_matching_state->following_sibling_nodes
            : empty_nodes;
    if (GatherNodeModificationsAndUpdateTargetNodes(
            previous_sibling_following_sibling_nodes,
            &element_matching_state->previous_sibling_following_sibling_nodes,
            added_nodes, removed_nodes)) {
      element_matching_state->are_following_sibling_nodes_dirty = true;
      matching_nodes_modified |= UpdateMatchingNodesFromNodeModifications(
          *added_nodes, *removed_nodes, cssom::kFollowingSiblingCombinator,
          element, selector_tree->scratchpad_node_pairs());
    }
  }

  element_matching_state->is_set = true;

  // Matching node modifications may impact combinator nodes, so they must be
  // dirtied. However, they are lazily updated the first time that they are
  // needed by a child/following sibling, rather than immediately updated. This
  // prevents unnecessary updates of leaf elements and last sibling elements.
  if (matching_nodes_modified) {
    element_matching_state->are_descendant_nodes_dirty = true;
    element_matching_state->are_following_sibling_nodes_dirty = true;
  }

  return matching_nodes_modified;
}

void UpdateElementMatchingRulesFromRuleMatchingState(HTMLElement* element) {
  Document* element_document = element->node_document();

  // Store the element's and its pseudo element's old matching rules so that
  // they can be compared to the new matching rules after they are generated.
  cssom::RulesWithCascadePrecedence* element_old_matching_rules =
      element_document->scratchpad_html_element_matching_rules();
  *element_old_matching_rules = std::move(*element->matching_rules());
  element->matching_rules()->clear();

  for (int type = 0; type < kMaxPseudoElementType; ++type) {
    PseudoElement* pseudo_element =
        element->pseudo_element(PseudoElementType(type));
    if (pseudo_element) {
      cssom::RulesWithCascadePrecedence* old_pseudo_element_matching_rules =
          element_document->scratchpad_pseudo_element_matching_rules(
              PseudoElementType(type));
      *old_pseudo_element_matching_rules =
          std::move(*pseudo_element->matching_rules());
      pseudo_element->matching_rules()->clear();
    }
  }

  // Walk all matching nodes, generating matching rules for the element and
  // its pseudo elements from them.
  for (const auto& node : element->rule_matching_state()->matching_nodes) {
    // Determine the matching rules that this specific node targets. If the
    // node does not have a pseudo element, then this will be the element's
    // matching rules; otherwise, it'll be the matching rules associated with
    // the pseudo element's type.
    cssom::RulesWithCascadePrecedence* target_matching_rules;

    cssom::PseudoElement* pseudo_element =
        node->compound_selector()->pseudo_element();
    if (!pseudo_element) {
      target_matching_rules = element->matching_rules();
    } else {
      PseudoElementType pseudo_element_type = kNotPseudoElementType;

      if (pseudo_element->AsAfterPseudoElement()) {
        pseudo_element_type = kAfterPseudoElementType;
      } else if (pseudo_element->AsBeforePseudoElement()) {
        pseudo_element_type = kBeforePseudoElementType;
      } else {
        NOTREACHED();
      }

      // Make sure the pseudo element exists under element. If not, create it
      // and clear out the old matching rules since the pseudo element had no
      // pre-existing matching rules.
      if (!element->pseudo_element(pseudo_element_type)) {
        element->SetPseudoElement(
            pseudo_element_type,
            base::WrapUnique(new dom::PseudoElement(element)));

        cssom::RulesWithCascadePrecedence* old_pseudo_element_matching_rules =
            element_document->scratchpad_pseudo_element_matching_rules(
                PseudoElementType(pseudo_element_type));
        old_pseudo_element_matching_rules->clear();
      }

      target_matching_rules =
          element->pseudo_element(pseudo_element_type)->matching_rules();
    }

    // Add all of the node's rules to the target matching rules.
    for (const auto& weak_rule : node->rules()) {
      const auto rule = weak_rule.get();
      if (!rule) {
        continue;
      }
      DCHECK(rule->parent_style_sheet());
      cssom::CascadePrecedence precedence(
          pseudo_element ? cssom::kNormalOverride
                         : rule->parent_style_sheet()->origin(),
          node->cumulative_specificity(),
          cssom::Appearance(rule->parent_style_sheet()->index(),
                            rule->index()));
      target_matching_rules->push_back(std::make_pair(rule, precedence));
    }
  }

  // Check for if the newly generated matching rules are different for the
  // element or its pseudo elements.
  if (*element_old_matching_rules != *element->matching_rules()) {
    element->OnMatchingRulesModified();
  }

  for (int type = 0; type < kMaxPseudoElementType; ++type) {
    PseudoElement* pseudo_element =
        element->pseudo_element(PseudoElementType(type));
    if (pseudo_element) {
      cssom::RulesWithCascadePrecedence* old_pseudo_element_matching_rules =
          element_document->scratchpad_pseudo_element_matching_rules(
              PseudoElementType(type));
      if (*old_pseudo_element_matching_rules !=
          *pseudo_element->matching_rules()) {
        pseudo_element->set_computed_style_invalid();
        element->OnPseudoElementMatchingRulesModified();
      }
    }
  }
}

}  // namespace

//////////////////////////////////////////////////////////////////////////
// Public APIs
//////////////////////////////////////////////////////////////////////////

void UpdateElementMatchingRules(HTMLElement* element) {
  DCHECK(element);
  DCHECK(element->node_document());
  if (element->matching_rules_valid()) {
    return;
  }

  // Only update the matching rules if the rule matching state is modified.
  if (UpdateElementRuleMatchingState(element)) {
    UpdateElementMatchingRulesFromRuleMatchingState(element);
  }

  element->set_matching_rules_valid();
}

scoped_refptr<Element> QuerySelector(Node* node, const std::string& selectors,
                                     cssom::CSSParser* css_parser) {
  DCHECK(css_parser);

  // Generate a rule with the given selectors and no style.
  scoped_refptr<cssom::CSSRule> css_rule =
      css_parser->ParseRule(selectors + " {}", node->GetInlineSourceLocation());
  if (!css_rule) {
    return NULL;
  }
  scoped_refptr<cssom::CSSStyleRule> css_style_rule =
      css_rule->AsCSSStyleRule();
  if (!css_style_rule) {
    return NULL;
  }

  // Iterate through the descendants of the node and find the first matching
  // element if any.
  NodeDescendantsIterator iterator(node);
  Node* child = iterator.First();
  while (child) {
    if (child->IsElement()) {
      scoped_refptr<Element> element = child->AsElement();
      if (MatchRuleAndElement(css_style_rule, element)) {
        return element;
      }
    }
    child = iterator.Next();
  }
  return NULL;
}

bool MatchRuleAndElement(cssom::CSSStyleRule* rule, Element* element) {
  for (cssom::Selectors::const_iterator selector_iterator =
           rule->selectors().begin();
       selector_iterator != rule->selectors().end(); ++selector_iterator) {
    DCHECK(*selector_iterator);
    if (MatchSelectorAndElement(selector_iterator->get(), element, true)) {
      return true;
    }
  }
  return false;
}

scoped_refptr<NodeList> QuerySelectorAll(Node* node,
                                         const std::string& selectors,
                                         cssom::CSSParser* css_parser) {
  DCHECK(css_parser);

  scoped_refptr<NodeList> node_list = new NodeList();

  // Generate a rule with the given selectors and no style.
  scoped_refptr<cssom::CSSRule> css_rule =
      css_parser->ParseRule(selectors + " {}", node->GetInlineSourceLocation());
  if (!css_rule) {
    return node_list;
  }
  scoped_refptr<cssom::CSSStyleRule> css_style_rule =
      css_rule->AsCSSStyleRule();
  if (!css_style_rule) {
    return node_list;
  }

  // Iterate through the descendants of the node and find the matching elements.
  NodeDescendantsIterator iterator(node);
  Node* child = iterator.First();
  while (child) {
    if (child->IsElement()) {
      scoped_refptr<Element> element = child->AsElement();
      if (MatchRuleAndElement(css_style_rule, element)) {
        node_list->AppendNode(element);
      }
    }
    child = iterator.Next();
  }
  return node_list;
}

}  // namespace dom
}  // namespace cobalt
