// 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/cssom/selector_tree.h"

#include "cobalt/base/version_compatibility.h"
#include "cobalt/css_parser/parser.h"
#include "cobalt/cssom/css_style_rule.h"
#include "cobalt/cssom/specificity.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

TEST(SelectorTreeTest, RootShouldHaveNoChildrenAfterInitialization) {
  SelectorTree selector_tree;
  EXPECT_TRUE(
      selector_tree.children(selector_tree.root_node(), kChildCombinator)
          .empty());
  EXPECT_TRUE(
      selector_tree.children(selector_tree.root_node(), kDescendantCombinator)
          .empty());
  EXPECT_TRUE(
      selector_tree.children(selector_tree.root_node(), kNextSiblingCombinator)
          .empty());
  EXPECT_TRUE(
      selector_tree
          .children(selector_tree.root_node(), kFollowingSiblingCombinator)
          .empty());
}

TEST(SelectorTreeTest, AppendRuleShouldTakeOneRule) {
  SelectorTree selector_tree;

  // Selector Tree:
  // root
  //   kDescendantCombinator -> node_1("div")
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser->ParseRule("div {}", base::SourceLocation(
                                          "[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  selector_tree.AppendRule(css_style_rule_1);

  // Verify that ValidateVersionCompatibility does not report a usage error
  // when the minimum compatibility version is 1.
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(1);
  EXPECT_TRUE(selector_tree.ValidateVersionCompatibility());

  ASSERT_EQ(0,
            selector_tree.children(selector_tree.root_node(), kChildCombinator)
                .size());
  ASSERT_EQ(1, selector_tree
                   .children(selector_tree.root_node(), kDescendantCombinator)
                   .size());
  ASSERT_EQ(0, selector_tree
                   .children(selector_tree.root_node(), kNextSiblingCombinator)
                   .size());
  ASSERT_EQ(
      0, selector_tree
             .children(selector_tree.root_node(), kFollowingSiblingCombinator)
             .size());

  const SelectorTree::Node* node_1 =
      selector_tree.children(selector_tree.root_node(), kDescendantCombinator)
          .begin()
          ->second;
  ASSERT_EQ(1, node_1->rules().size());
  EXPECT_EQ(css_style_rule_1, node_1->rules()[0]);
  EXPECT_EQ(Specificity(0, 0, 1), node_1->cumulative_specificity());
}

TEST(SelectorTreeTest, AppendRuleShouldNormalizeCompoundSelector) {
  SelectorTree selector_tree;

  // Selector Tree:
  // root
  //   kDescendantCombinator -> node_1(".class#id")
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser->ParseRule(
                    ".class#id {}",
                    base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser->ParseRule(
                    "#id.class {}",
                    base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  selector_tree.AppendRule(css_style_rule_1);
  selector_tree.AppendRule(css_style_rule_2);

  // Verify that ValidateVersionCompatibility does not report a usage error
  // when the minimum compatibility version is 1.
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(1);
  EXPECT_TRUE(selector_tree.ValidateVersionCompatibility());

  ASSERT_EQ(0,
            selector_tree.children(selector_tree.root_node(), kChildCombinator)
                .size());
  ASSERT_EQ(1, selector_tree
                   .children(selector_tree.root_node(), kDescendantCombinator)
                   .size());
  ASSERT_EQ(0, selector_tree
                   .children(selector_tree.root_node(), kNextSiblingCombinator)
                   .size());
  ASSERT_EQ(
      0, selector_tree
             .children(selector_tree.root_node(), kFollowingSiblingCombinator)
             .size());
}

TEST(SelectorTreeTest, AppendRuleSimpleShouldTakeTwoIdenticalRules) {
  SelectorTree selector_tree;

  // Selector Tree:
  // root
  //   kDescendantCombinator -> node_1("div")
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser->ParseRule("div {}", base::SourceLocation(
                                          "[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser->ParseRule("div {}", base::SourceLocation(
                                          "[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  selector_tree.AppendRule(css_style_rule_1);
  selector_tree.AppendRule(css_style_rule_2);

  // Verify that ValidateVersionCompatibility does not report a usage error
  // when the minimum compatibility version is 1.
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(1);
  EXPECT_TRUE(selector_tree.ValidateVersionCompatibility());

  ASSERT_EQ(0,
            selector_tree.children(selector_tree.root_node(), kChildCombinator)
                .size());
  ASSERT_EQ(1, selector_tree
                   .children(selector_tree.root_node(), kDescendantCombinator)
                   .size());
  ASSERT_EQ(0, selector_tree
                   .children(selector_tree.root_node(), kNextSiblingCombinator)
                   .size());
  ASSERT_EQ(
      0, selector_tree
             .children(selector_tree.root_node(), kFollowingSiblingCombinator)
             .size());
  const SelectorTree::Node* node_1 =
      selector_tree.children(selector_tree.root_node(), kDescendantCombinator)
          .begin()
          ->second;
  ASSERT_EQ(2, node_1->rules().size());
  EXPECT_EQ(css_style_rule_1, node_1->rules()[0]);
  EXPECT_EQ(css_style_rule_2, node_1->rules()[1]);
  EXPECT_EQ(Specificity(0, 0, 1), node_1->cumulative_specificity());
}

TEST(SelectorTreeTest, AppendRuleSimpleShouldTakeTwoDesendantSelectors) {
  SelectorTree selector_tree;

  // Selector Tree:
  // root
  //   kNone -> node_1("div")
  //     kChildCombinator -> node_2("span")
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser->ParseRule("div {}", base::SourceLocation(
                                          "[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser->ParseRule(
                    "div span {}",
                    base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  selector_tree.AppendRule(css_style_rule_1);
  selector_tree.AppendRule(css_style_rule_2);

  // Verify that ValidateVersionCompatibility does not report a usage error
  // when the minimum compatibility version is 1.
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(1);
  EXPECT_TRUE(selector_tree.ValidateVersionCompatibility());

  ASSERT_EQ(0,
            selector_tree.children(selector_tree.root_node(), kChildCombinator)
                .size());
  ASSERT_EQ(1, selector_tree
                   .children(selector_tree.root_node(), kDescendantCombinator)
                   .size());
  ASSERT_EQ(0, selector_tree
                   .children(selector_tree.root_node(), kNextSiblingCombinator)
                   .size());
  ASSERT_EQ(
      0, selector_tree
             .children(selector_tree.root_node(), kFollowingSiblingCombinator)
             .size());
  const SelectorTree::Node* node_1 =
      selector_tree.children(selector_tree.root_node(), kDescendantCombinator)
          .begin()
          ->second;
  ASSERT_EQ(1, node_1->rules().size());
  EXPECT_EQ(css_style_rule_1, node_1->rules()[0]);
  EXPECT_EQ(Specificity(0, 0, 1), node_1->cumulative_specificity());

  ASSERT_EQ(0, selector_tree.children(node_1, kChildCombinator).size());
  ASSERT_EQ(1, selector_tree.children(node_1, kDescendantCombinator).size());
  ASSERT_EQ(0, selector_tree.children(node_1, kNextSiblingCombinator).size());
  ASSERT_EQ(0,
            selector_tree.children(node_1, kFollowingSiblingCombinator).size());
  const SelectorTree::Node* node_2 =
      selector_tree.children(node_1, kDescendantCombinator).begin()->second;
  ASSERT_EQ(1, node_2->rules().size());
  EXPECT_EQ(css_style_rule_2, node_2->rules()[0]);
  EXPECT_EQ(Specificity(0, 0, 2), node_2->cumulative_specificity());
}

TEST(SelectorTreeTest, AppendRuleTwoDifferentNotSelectorsForSameElement) {
  SelectorTree selector_tree;

  // Selector Tree:
  // root
  //   kDescendantCombinator -> node_1("body:not(.class-1)")
  //   kDescendantCombinator -> node_2("body:not(.class-2)")
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser
          ->ParseRule("body:not(.class-1) {}",
                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser
          ->ParseRule("body:not(.class-2) {}",
                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  selector_tree.AppendRule(css_style_rule_1);
  selector_tree.AppendRule(css_style_rule_2);

  // Verify that ValidateVersionCompatibility does not report a usage error
  // when the minimum compatibility version is 16.
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(16);
  EXPECT_TRUE(selector_tree.ValidateVersionCompatibility());

  // Verify that ValidateVersionCompatibility reports a usage error when the
  // minimum compatibility version is 1.
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(1);
  EXPECT_FALSE(selector_tree.ValidateVersionCompatibility());

  ASSERT_EQ(0,
            selector_tree.children(selector_tree.root_node(), kChildCombinator)
                .size());
  ASSERT_EQ(2, selector_tree
                   .children(selector_tree.root_node(), kDescendantCombinator)
                   .size());
  ASSERT_EQ(0, selector_tree
                   .children(selector_tree.root_node(), kNextSiblingCombinator)
                   .size());
  ASSERT_EQ(
      0, selector_tree
             .children(selector_tree.root_node(), kFollowingSiblingCombinator)
             .size());
  auto node_iter =
      selector_tree.children(selector_tree.root_node(), kDescendantCombinator)
          .begin();
  const SelectorTree::Node* node_1 = node_iter->second;
  ASSERT_EQ(1, node_1->rules().size());
  EXPECT_EQ(css_style_rule_1, node_1->rules()[0]);
  EXPECT_EQ(Specificity(0, 1, 1), node_1->cumulative_specificity());

  const SelectorTree::Node* node_2 = (++node_iter)->second;
  ASSERT_EQ(1, node_2->rules().size());
  EXPECT_EQ(css_style_rule_2, node_2->rules()[0]);
  EXPECT_EQ(Specificity(0, 1, 1), node_1->cumulative_specificity());
}

TEST(SelectorTreeTest, AppendRuleTwoNotSelectorsForDifferentElements) {
  SelectorTree selector_tree;

  // Selector Tree:
  // root
  //   kDescendantCombinator -> node_1("body:not(.class-1)")
  //   kDescendantCombinator -> node_2("div:not(.class-1)")
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser
          ->ParseRule("body:not(.class-1) {}",
                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser
          ->ParseRule("div:not(.class-1) {}",
                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  selector_tree.AppendRule(css_style_rule_1);
  selector_tree.AppendRule(css_style_rule_2);

  // Verify that ValidateVersionCompatibility does not report a usage error
  // when the minimum compatibility version is 1.
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(1);
  EXPECT_TRUE(selector_tree.ValidateVersionCompatibility());

  ASSERT_EQ(0,
            selector_tree.children(selector_tree.root_node(), kChildCombinator)
                .size());
  ASSERT_EQ(2, selector_tree
                   .children(selector_tree.root_node(), kDescendantCombinator)
                   .size());
  ASSERT_EQ(0, selector_tree
                   .children(selector_tree.root_node(), kNextSiblingCombinator)
                   .size());
  ASSERT_EQ(
      0, selector_tree
             .children(selector_tree.root_node(), kFollowingSiblingCombinator)
             .size());
  auto node_iter =
      selector_tree.children(selector_tree.root_node(), kDescendantCombinator)
          .begin();
  const SelectorTree::Node* node_1 = node_iter->second;
  ASSERT_EQ(1, node_1->rules().size());
  EXPECT_EQ(css_style_rule_1, node_1->rules()[0]);
  EXPECT_EQ(Specificity(0, 1, 1), node_1->cumulative_specificity());

  const SelectorTree::Node* node_2 = (++node_iter)->second;
  ASSERT_EQ(1, node_2->rules().size());
  EXPECT_EQ(css_style_rule_2, node_2->rules()[0]);
  EXPECT_EQ(Specificity(0, 1, 1), node_1->cumulative_specificity());
}

TEST(SelectorTreeTest, AppendRuleTwoIdenticalNotSelectors) {
  SelectorTree selector_tree;

  // Selector Tree:
  // root
  //   kDescendantCombinator -> node_1("body:not(.class-1")
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser
          ->ParseRule("body:not(.class-1) {}",
                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser
          ->ParseRule("body:not(.class-1) {}",
                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
          ->AsCSSStyleRule();
  selector_tree.AppendRule(css_style_rule_1);
  selector_tree.AppendRule(css_style_rule_2);

  // Verify that ValidateVersionCompatibility does not report a usage error
  // when the minimum compatibility version is 1.
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(1);
  EXPECT_TRUE(selector_tree.ValidateVersionCompatibility());

  ASSERT_EQ(0,
            selector_tree.children(selector_tree.root_node(), kChildCombinator)
                .size());
  ASSERT_EQ(1, selector_tree
                   .children(selector_tree.root_node(), kDescendantCombinator)
                   .size());
  ASSERT_EQ(0, selector_tree
                   .children(selector_tree.root_node(), kNextSiblingCombinator)
                   .size());
  ASSERT_EQ(
      0, selector_tree
             .children(selector_tree.root_node(), kFollowingSiblingCombinator)
             .size());
  const SelectorTree::Node* node_1 =
      selector_tree.children(selector_tree.root_node(), kDescendantCombinator)
          .begin()
          ->second;
  ASSERT_EQ(2, node_1->rules().size());
  EXPECT_EQ(css_style_rule_1, node_1->rules()[0]);
  EXPECT_EQ(css_style_rule_2, node_1->rules()[1]);
  EXPECT_EQ(Specificity(0, 1, 1), node_1->cumulative_specificity());
}

}  // namespace cssom
}  // namespace cobalt
