// Copyright 2016 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_computed_style_data.h"
#include "cobalt/cssom/css_computed_style_declaration.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/cssom/length_value.h"
#include "cobalt/cssom/property_definitions.h"
#include "cobalt/dom/testing/fake_exception_state.h"
#include "cobalt/script/exception_state.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

using ::testing::_;
using ::testing::Return;
using dom::testing::FakeExceptionState;

TEST(CSSComputedStyleDeclarationTest, CSSTextSetterRaisesException) {
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  FakeExceptionState exception_state;

  const std::string css_text = "font-size: 100px; color: #0047ab;";
  style->set_css_text(css_text, &exception_state);
  EXPECT_EQ(dom::DOMException::kInvalidAccessErr,
            exception_state.GetExceptionCode());
}

TEST(CSSComputedStyleDeclarationTest, DISABLED_CSSTextGetter) {
  scoped_refptr<LengthValue> background_size =
      new LengthValue(100, kPixelsUnit);
  scoped_refptr<LengthValue> bottom = new LengthValue(16, kPixelsUnit);

  scoped_refptr<CSSComputedStyleData> style_data = new CSSComputedStyleData();
  style_data->SetPropertyValue(kBackgroundSizeProperty, background_size);
  style_data->SetPropertyValue(kBottomProperty, bottom);

  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  style->SetData(style_data);
  EXPECT_EQ(style->css_text(NULL), "background-size: 100px; bottom: 16px;");
}

TEST(CSSComputedStyleDeclarationTest, PropertyValueSetterRaisesException) {
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  const std::string background = "rgba(0, 0, 0, .8)";
  FakeExceptionState exception_state;

  style->SetPropertyValue(GetPropertyName(kBackgroundProperty), background,
                          &exception_state);
  EXPECT_EQ(dom::DOMException::kInvalidAccessErr,
            exception_state.GetExceptionCode());
}

TEST(CSSComputedStyleDeclarationTest,
     PropertySetterWithTwoValuesRaisesException) {
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  const std::string background = "rgba(0, 0, 0, .8)";
  FakeExceptionState exception_state;

  style->SetProperty(GetPropertyName(kBackgroundProperty), background,
                     &exception_state);
  EXPECT_EQ(dom::DOMException::kInvalidAccessErr,
            exception_state.GetExceptionCode());
}

TEST(CSSComputedStyleDeclarationTest,
     PropertySetterWithThreeValuesRaisesException) {
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  const std::string background = "rgba(0, 0, 0, .8)";
  FakeExceptionState exception_state;

  style->SetProperty(GetPropertyName(kBackgroundProperty), background,
                     std::string(), &exception_state);
  EXPECT_EQ(dom::DOMException::kInvalidAccessErr,
            exception_state.GetExceptionCode());
}

TEST(CSSComputedStyleDeclarationTest, RemovePropertyRaisesException) {
  scoped_refptr<CSSComputedStyleData> initial_style =
      new CSSComputedStyleData();
  initial_style->SetPropertyValue(kDisplayProperty, KeywordValue::GetInline());
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  style->SetData(initial_style);

  const std::string background = "rgba(0, 0, 0, .8)";
  FakeExceptionState exception_state;

  style->RemoveProperty(GetPropertyName(kDisplayProperty), &exception_state);
  EXPECT_EQ(dom::DOMException::kInvalidAccessErr,
            exception_state.GetExceptionCode());
}

TEST(CSSComputedStyleDeclarationTest, PropertyValueGetter) {
  scoped_refptr<CSSComputedStyleData> initial_style =
      new CSSComputedStyleData();
  initial_style->SetPropertyValue(kTextAlignProperty,
                                  KeywordValue::GetCenter());
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  style->SetData(initial_style);

  EXPECT_EQ(style->GetPropertyValue(GetPropertyName(kTextAlignProperty)),
            "center");
}

TEST(CSSComputedStyleDeclarationTest,
     UnknownDeclaredStylePropertyValueShouldBeEmpty) {
  scoped_refptr<CSSComputedStyleData> initial_style =
      new CSSComputedStyleData();
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  style->SetData(initial_style);

  EXPECT_EQ(style->GetPropertyValue("cobalt_cobalt_cobalt"), "");
}

TEST(CSSComputedStyleDeclarationTest, LengthAttributeGetterEmpty) {
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();

  EXPECT_EQ(style->length(), kMaxLonghandPropertyKey + 1);
}

TEST(CSSComputedStyleDeclarationTest, LengthAttributeGetterNotEmpty) {
  scoped_refptr<CSSComputedStyleData> initial_style =
      new CSSComputedStyleData();
  initial_style->SetPropertyValue(kDisplayProperty, KeywordValue::GetInline());
  initial_style->SetPropertyValue(kTextAlignProperty,
                                  KeywordValue::GetCenter());
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  style->SetData(initial_style);

  EXPECT_EQ(style->length(), kMaxLonghandPropertyKey + 1);
}

TEST(CSSComputedStyleDeclarationTest, ItemGetterEmpty) {
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();

  // Computed styles are never actually empty.
  EXPECT_TRUE(style->Item(0));
}

TEST(CSSComputedStyleDeclarationTest, ItemGetterNotEmpty) {
  scoped_refptr<CSSComputedStyleData> initial_style =
      new CSSComputedStyleData();
  initial_style->SetPropertyValue(kDisplayProperty, KeywordValue::GetInline());
  initial_style->SetPropertyValue(kTextAlignProperty,
                                  KeywordValue::GetCenter());
  scoped_refptr<CSSComputedStyleDeclaration> style =
      new CSSComputedStyleDeclaration();
  style->SetData(initial_style);

  int property_count = 0;
  for (unsigned int key = 0; key <= kMaxLonghandPropertyKey; ++key) {
    // The order is not important, as long as all properties are represented.
    EXPECT_TRUE(style->Item(key));
    if (style->Item(key).value() == GetPropertyName(kDisplayProperty)) {
      ++property_count;
    }
    if (style->Item(key).value() == GetPropertyName(kTextAlignProperty)) {
      ++property_count;
    }
  }
  EXPECT_EQ(property_count, 2);
}

}  // namespace cssom
}  // namespace cobalt
