/*
 * Copyright 2014 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.
 */

#include "cobalt/cssom/css_rule_list.h"

#include "cobalt/cssom/css_media_rule.h"
#include "cobalt/cssom/css_parser.h"
#include "cobalt/cssom/css_rule_style_declaration.h"
#include "cobalt/cssom/css_style_declaration.h"
#include "cobalt/cssom/css_style_rule.h"
#include "cobalt/cssom/css_style_sheet.h"
#include "cobalt/cssom/length_value.h"
#include "cobalt/cssom/media_feature.h"
#include "cobalt/cssom/media_feature_keyword_value.h"
#include "cobalt/cssom/media_feature_names.h"
#include "cobalt/cssom/media_list.h"
#include "cobalt/cssom/media_query.h"
#include "cobalt/cssom/selector.h"
#include "cobalt/cssom/style_sheet_list.h"
#include "cobalt/cssom/testing/mock_css_parser.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

using ::testing::_;
using ::testing::Return;

class MockMutationObserver : public MutationObserver {
 public:
  MOCK_METHOD0(OnCSSMutation, void());
};

class CSSStyleSheetTest : public ::testing::Test {
 protected:
  CSSStyleSheetTest()
      : style_sheet_list_(new StyleSheetList(&mutation_observer_)),
        css_style_sheet_(new CSSStyleSheet(&css_parser_)) {
    css_style_sheet_->AttachToStyleSheetList(style_sheet_list_);
  }
  ~CSSStyleSheetTest() OVERRIDE {}

  MockMutationObserver mutation_observer_;
  const scoped_refptr<StyleSheetList> style_sheet_list_;
  const scoped_refptr<CSSStyleSheet> css_style_sheet_;
  testing::MockCSSParser css_parser_;
};

TEST_F(CSSStyleSheetTest, InsertRule) {
  const std::string css_text = "div { font-size: 100px; color: #0047ab; }";

  EXPECT_CALL(css_parser_, ParseRule(css_text, _))
      .WillOnce(Return(scoped_refptr<CSSRule>()));
  css_style_sheet_->InsertRule(css_text, 0);
}

TEST_F(CSSStyleSheetTest, CSSRuleListIsCached) {
  scoped_refptr<CSSRuleList> rule_list_1 = css_style_sheet_->css_rules();
  scoped_refptr<CSSRuleList> rule_list_2 = css_style_sheet_->css_rules();
  ASSERT_EQ(rule_list_1, rule_list_2);
}

TEST_F(CSSStyleSheetTest, CSSRuleListIsLive) {
  scoped_refptr<CSSRuleList> rule_list = css_style_sheet_->css_rules();
  ASSERT_EQ(0, rule_list->length());
  ASSERT_FALSE(rule_list->Item(0).get());

  scoped_refptr<CSSStyleRule> rule =
      new CSSStyleRule(Selectors(), new CSSRuleStyleDeclaration(NULL));

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(1);
  rule_list->AppendCSSRule(rule);
  css_style_sheet_->set_css_rules(rule_list);
  ASSERT_EQ(1, rule_list->length());
  ASSERT_EQ(rule, rule_list->Item(0));
  ASSERT_FALSE(rule_list->Item(1).get());
  ASSERT_EQ(rule_list, css_style_sheet_->css_rules());
}

TEST_F(CSSStyleSheetTest, CSSMutationIsReportedAtStyleSheetList) {
  // A call to OnCSSMutation on the CSSStyleSheet should result in a call to
  // OnCSSMutation in the MutationObserver registered with the StyleSheetList
  // that is the parent of the CSSStyleSheet.

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(1);
  css_style_sheet_->OnCSSMutation();
}

TEST_F(CSSStyleSheetTest, CSSMutationIsRecordedAfterMediaRuleAddition) {
  // When a CSSMediaRule is added to a CSSStyleSheet, it should result in a call
  // to OnCSSMutation() in the MutationObserver after the next call to
  // EvaluateMediaRules(), even when called with the same media parameters as
  // before. That also tests that OnMediaRuleMutation() should be called and
  // that the flag it sets should be honored.
  scoped_refptr<CSSRuleList> rule_list = css_style_sheet_->css_rules();
  // A CSSMediaRule with no expression always evaluates to true.
  scoped_refptr<CSSMediaRule> rule = new CSSMediaRule();

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(0);
  css_style_sheet_->EvaluateMediaRules(math::Size(1920, 1080));

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(1);
  rule_list->AppendCSSRule(rule);

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(1);
  css_style_sheet_->EvaluateMediaRules(math::Size(1920, 1080));
}

TEST_F(CSSStyleSheetTest, CSSMutationIsRecordedForAddingFalseMediaRule) {
  // Adding a CSSMediaRule that is false should result in a call to
  // OnCSSMutation() only when the rule is added, for the added MediaRule
  // itself. It should not call OnCSSMutation when it's evaluated, because no
  // rules are added or removed at that time for a new rule that is false.
  scoped_refptr<MediaQuery> media_query(new MediaQuery(false));
  scoped_refptr<MediaList> media_list(new MediaList());
  media_list->Append(media_query);
  scoped_refptr<CSSMediaRule> rule = new CSSMediaRule(media_list, NULL);
  scoped_refptr<CSSRuleList> rule_list = css_style_sheet_->css_rules();

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(1);
  rule_list->AppendCSSRule(rule);

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(0);
  css_style_sheet_->EvaluateMediaRules(math::Size(1920, 1080));
}

TEST_F(CSSStyleSheetTest, CSSMutationIsRecordedAfterMediaValueChanges) {
  // Changing a media value (width or height) should result in a call to
  // OnCSSMutation() if the media rule condition value changes.

  // We first need to build a CSSMediaRule that holds a media at-rule that
  // can change value. We choose '(orientation:landscape)'.
  scoped_refptr<MediaFeatureKeywordValue> property =
      MediaFeatureKeywordValue::GetLandscape();
  scoped_refptr<MediaFeature> media_feature(
      new MediaFeature(kOrientationMediaFeature, property));
  media_feature->set_operator(kEquals);
  scoped_ptr<MediaFeatures> media_features(new MediaFeatures);
  media_features->push_back(media_feature);
  scoped_refptr<MediaQuery> media_query(
      new MediaQuery(true, media_features.Pass()));
  scoped_refptr<MediaList> media_list(new MediaList());
  media_list->Append(media_query);
  scoped_refptr<CSSMediaRule> rule = new CSSMediaRule(media_list, NULL);

  // This should result in a call to OnCSSMutation(), because a media rule is
  // added to the style sheet.

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(1);
  css_style_sheet_->css_rules()->AppendCSSRule(rule);

  // This should result in a call to OnCSSMutation(), because the added media
  // rule evaluates to true, so its rule list needs to be traversed for the next
  // rule matching.

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(1);
  css_style_sheet_->EvaluateMediaRules(math::Size(1920, 1080));

  // This should not result in a call to OnCSSMutation(), because changing the
  // width to 1280 does not change the CSSMediaRule condition.

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(0);
  css_style_sheet_->EvaluateMediaRules(math::Size(1280, 1080));

  // This should result in a call to OnCSSMutation(), because changing the width
  // to 640 makes the CSSMediaRule condition change. The display orientation is
  // now Portrait instead of Landscape.

  EXPECT_CALL(mutation_observer_, OnCSSMutation()).Times(1);
  css_style_sheet_->EvaluateMediaRules(math::Size(640, 1080));
}

}  // namespace cssom
}  // namespace cobalt
