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

#include "cobalt/css_parser/parser.h"
#include "cobalt/cssom/cascade_precedence.h"
#include "cobalt/cssom/css_computed_style_data.h"
#include "cobalt/cssom/css_declaration_data.h"
#include "cobalt/cssom/css_declared_style_data.h"
#include "cobalt/cssom/css_rule_style_declaration.h"
#include "cobalt/cssom/css_style_rule.h"
#include "cobalt/cssom/css_style_sheet.h"
#include "cobalt/cssom/keyword_value.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

TEST(CascadedStyleTest, PromoteToCascadedStyle) {
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData();
  RulesWithCascadePrecedence rules_with_cascade_precedence;
  GURLMap property_key_to_base_url_map;

  style->SetPropertyValueAndImportance(kVerticalAlignProperty,
                                       KeywordValue::GetBottom(), true);
  style->SetPropertyValueAndImportance(kTextAlignProperty,
                                       KeywordValue::GetLeft(), false);

  // The order of cascade precedence of the following rules:
  // rule 2 > rule 3 > rule 1.

  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser->ParseRule(
                    "div {"
                    "  left: 100px !important;"
                    "  right: 100px;"
                    "  width: 100px;"
                    "  height: 100px;"
                    "}",
                    base::SourceLocation("[object CascadedStyleTest]", 1, 1))
          ->AsCSSStyleRule();
  CascadePrecedence cascade_precedence_1(kNormalUserAgent);
  rules_with_cascade_precedence.push_back(
      std::make_pair(css_style_rule_1, cascade_precedence_1));

  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser->ParseRule(
                    "div {"
                    "  left: 200px;"
                    "  right: 200px !important;"
                    "  width: 200px;"
                    "  height: 200px;"
                    "  vertical-align: top !important;"
                    "  text-align: center !important;"
                    "}",
                    base::SourceLocation("[object CascadedStyleTest]", 1, 1))
          ->AsCSSStyleRule();
  CascadePrecedence cascade_precedence_2(kNormalOverride);
  rules_with_cascade_precedence.push_back(
      std::make_pair(css_style_rule_2, cascade_precedence_2));

  scoped_refptr<CSSStyleRule> css_style_rule_3 =
      css_parser->ParseRule(
                    "div {"
                    "  left: 300px;"
                    "  right: 300px;"
                    "  width: 300px !important;"
                    "  height: 300px;"
                    "}",
                    base::SourceLocation("[object CascadedStyleTest]", 1, 1))
          ->AsCSSStyleRule();
  CascadePrecedence cascade_precedence_3(kNormalAuthor);
  rules_with_cascade_precedence.push_back(
      std::make_pair(css_style_rule_3, cascade_precedence_3));

  scoped_refptr<CSSComputedStyleData> computed_style = PromoteToCascadedStyle(
      style, &rules_with_cascade_precedence, &property_key_to_base_url_map);

  EXPECT_EQ(
      computed_style->left(),
      css_style_rule_1->declared_style_data()->GetPropertyValue(kLeftProperty));
  EXPECT_EQ(computed_style->right(),
            css_style_rule_2->declared_style_data()->GetPropertyValue(
                kRightProperty));
  EXPECT_EQ(computed_style->width(),
            css_style_rule_3->declared_style_data()->GetPropertyValue(
                kWidthProperty));
  EXPECT_EQ(computed_style->height(),
            css_style_rule_2->declared_style_data()->GetPropertyValue(
                kHeightProperty));
  EXPECT_EQ(computed_style->vertical_align(),
            style->GetPropertyValue(kVerticalAlignProperty));
  EXPECT_EQ(computed_style->text_align(),
            css_style_rule_2->declared_style_data()->GetPropertyValue(
                kTextAlignProperty));
}

TEST(CascadedStyleTest, PromoteToCascadedStyleWithBackgroundImage) {
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData();
  RulesWithCascadePrecedence rules_with_cascade_precedence;
  GURLMap property_key_to_base_url_map;

  // The order of cascade precedence of the following rules:
  // rule 2 > rule 1.

  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser->ParseRule(
                    "div {"
                    "  left: 100px !important;"
                    "  right: 100px;"
                    "}",
                    base::SourceLocation("[object CascadedStyleTest]", 1, 1))
          ->AsCSSStyleRule();
  CascadePrecedence cascade_precedence_1(kNormalUserAgent);
  rules_with_cascade_precedence.push_back(
      std::make_pair(css_style_rule_1, cascade_precedence_1));

  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser->ParseRule(
                    "div {"
                    "  left: 200px;"
                    "  right: 200px !important;"
                    "  background-image: url(foo.png);"
                    "}",
                    base::SourceLocation("[object CascadedStyleTest]", 1, 1))
          ->AsCSSStyleRule();
  CascadePrecedence cascade_precedence_2(kNormalOverride);
  rules_with_cascade_precedence.push_back(
      std::make_pair(css_style_rule_2, cascade_precedence_2));

  scoped_refptr<CSSStyleSheet> parent_style_sheet(new CSSStyleSheet());
  parent_style_sheet->SetOriginClean(true);
  parent_style_sheet->SetLocationUrl(GURL("https:///www.youtube.com/tv/img"));
  css_style_rule_2->set_parent_style_sheet(parent_style_sheet.get());

  scoped_refptr<CSSComputedStyleData> computed_style = PromoteToCascadedStyle(
      style, &rules_with_cascade_precedence, &property_key_to_base_url_map);

  EXPECT_EQ(
      computed_style->left(),
      css_style_rule_1->declared_style_data()->GetPropertyValue(kLeftProperty));
  EXPECT_EQ(computed_style->right(),
            css_style_rule_2->declared_style_data()->GetPropertyValue(
                kRightProperty));
  EXPECT_EQ(computed_style->background_image(),
            css_style_rule_2->declared_style_data()->GetPropertyValue(
                kBackgroundImageProperty));
  ASSERT_FALSE(property_key_to_base_url_map.empty());
  EXPECT_EQ(property_key_to_base_url_map[kBackgroundImageProperty].spec(),
            "https://www.youtube.com/tv/img");
}

TEST(CascadedStyleTest,
     PromoteToCascadedStyleWithParentStyleSheetLocationUnset) {
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData();
  RulesWithCascadePrecedence rules_with_cascade_precedence;
  GURLMap property_key_to_base_url_map;
  property_key_to_base_url_map[kBackgroundImageProperty] =
      GURL("https://www.youtube.com/tv/img");

  scoped_refptr<CSSStyleRule> css_style_rule =
      css_parser->ParseRule(
                    "div {"
                    "  left: 200px;"
                    "  right: 200px !important;"
                    "  background-image: url(foo.png);"
                    "}",
                    base::SourceLocation("[object CascadedStyleTest]", 1, 1))
          ->AsCSSStyleRule();
  CascadePrecedence cascade_precedence(kNormalOverride);
  rules_with_cascade_precedence.push_back(
      std::make_pair(css_style_rule, cascade_precedence));

  scoped_refptr<CSSStyleSheet> parent_style_sheet(new CSSStyleSheet());
  parent_style_sheet->SetOriginClean(true);
  css_style_rule->set_parent_style_sheet(parent_style_sheet.get());

  scoped_refptr<CSSComputedStyleData> computed_style = PromoteToCascadedStyle(
      style, &rules_with_cascade_precedence, &property_key_to_base_url_map);

  EXPECT_EQ(
      computed_style->left(),
      css_style_rule->declared_style_data()->GetPropertyValue(kLeftProperty));
  EXPECT_EQ(
      computed_style->right(),
      css_style_rule->declared_style_data()->GetPropertyValue(kRightProperty));
  EXPECT_EQ(computed_style->background_image(),
            css_style_rule->declared_style_data()->GetPropertyValue(
                kBackgroundImageProperty));
  ASSERT_FALSE(property_key_to_base_url_map.empty());
  EXPECT_EQ(property_key_to_base_url_map[kBackgroundImageProperty].spec(),
            "https://www.youtube.com/tv/img");
}

TEST(CascadedStyleTest,
     PromoteToCascadedStyleWithHigherBackgroundImagePriorityInFirstRule) {
  scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
  scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData();
  RulesWithCascadePrecedence rules_with_cascade_precedence;
  GURLMap property_key_to_base_url_map;

  // The order of cascade precedence of the following rules:
  // rule 2 > rule 1.

  scoped_refptr<CSSStyleRule> css_style_rule_1 =
      css_parser->ParseRule(
                    "div {"
                    "  right: 100px;"
                    "  background-image: url(bar.png) !important;"
                    "}",
                    base::SourceLocation("[object CascadedStyleTest]", 1, 1))
          ->AsCSSStyleRule();
  CascadePrecedence cascade_precedence_1(kNormalUserAgent);
  rules_with_cascade_precedence.push_back(
      std::make_pair(css_style_rule_1, cascade_precedence_1));

  scoped_refptr<CSSStyleSheet> parent_style_sheet_1(new CSSStyleSheet());
  parent_style_sheet_1->SetLocationUrl(
      GURL("https:///www.youtube.com/tv/img1"));
  css_style_rule_1->set_parent_style_sheet(parent_style_sheet_1.get());

  scoped_refptr<CSSStyleRule> css_style_rule_2 =
      css_parser->ParseRule(
                    "div {"
                    "  right: 200px !important;"
                    "  background-image: url(foo.png);"
                    "}",
                    base::SourceLocation("[object CascadedStyleTest]", 1, 1))
          ->AsCSSStyleRule();
  CascadePrecedence cascade_precedence_2(kNormalOverride);
  rules_with_cascade_precedence.push_back(
      std::make_pair(css_style_rule_2, cascade_precedence_2));

  scoped_refptr<CSSStyleSheet> parent_style_sheet_2(new CSSStyleSheet());
  parent_style_sheet_2->SetLocationUrl(
      GURL("https:///www.youtube.com/tv/img2"));
  css_style_rule_2->set_parent_style_sheet(parent_style_sheet_2.get());

  scoped_refptr<CSSComputedStyleData> computed_style = PromoteToCascadedStyle(
      style, &rules_with_cascade_precedence, &property_key_to_base_url_map);

  EXPECT_EQ(computed_style->right(),
            css_style_rule_2->declared_style_data()->GetPropertyValue(
                kRightProperty));
  EXPECT_EQ(computed_style->background_image(),
            css_style_rule_1->declared_style_data()->GetPropertyValue(
                kBackgroundImageProperty));
  ASSERT_FALSE(property_key_to_base_url_map.empty());
  EXPECT_EQ(property_key_to_base_url_map[kBackgroundImageProperty].spec(),
            "https://www.youtube.com/tv/img1");
}

}  // namespace cssom
}  // namespace cobalt
