// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h"

#include <memory>
#include <utility>

#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_color_value.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_keyword_value.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_unit_value.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_unparsed_value.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_unsupported_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_unit_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_unparsed_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"

namespace blink {

class CrossThreadStyleValueTest : public testing::Test {
 public:
  void ShutDown(base::WaitableEvent* waitable_event) {
    DCHECK(!IsMainThread());
    waitable_event->Signal();
  }

  void ShutDownThread() {
    base::WaitableEvent waitable_event;
    PostCrossThreadTask(
        *thread_->GetTaskRunner(), FROM_HERE,
        CrossThreadBindOnce(&CrossThreadStyleValueTest::ShutDown,
                            CrossThreadUnretained(this),
                            CrossThreadUnretained(&waitable_event)));
    waitable_event.Wait();
  }

  void CheckUnsupportedValue(
      base::WaitableEvent* waitable_event,
      std::unique_ptr<CrossThreadUnsupportedValue> value) {
    DCHECK(!IsMainThread());

    EXPECT_EQ(value->value_, "Unsupported");
    waitable_event->Signal();
  }

  void CheckKeywordValue(base::WaitableEvent* waitable_event,
                         std::unique_ptr<CrossThreadKeywordValue> value) {
    DCHECK(!IsMainThread());

    EXPECT_EQ(value->keyword_value_, "Keyword");
    waitable_event->Signal();
  }

  void CheckUnparsedValue(base::WaitableEvent* waitable_event,
                          std::unique_ptr<CrossThreadUnparsedValue> value) {
    DCHECK(!IsMainThread());

    EXPECT_EQ(value->value_, "Unparsed");
    waitable_event->Signal();
  }

  void CheckUnitValue(base::WaitableEvent* waitable_event,
                      std::unique_ptr<CrossThreadUnitValue> value) {
    DCHECK(!IsMainThread());

    EXPECT_EQ(value->value_, 1);
    EXPECT_EQ(value->unit_, CSSPrimitiveValue::UnitType::kDegrees);
    waitable_event->Signal();
  }

  void CheckColorValue(base::WaitableEvent* waitable_event,
                       std::unique_ptr<CrossThreadColorValue> value) {
    DCHECK(!IsMainThread());

    EXPECT_EQ(value->value_, Color(0, 255, 0));
    waitable_event->Signal();
  }

 protected:
  std::unique_ptr<blink::Thread> thread_;
};

// Ensure that a CrossThreadUnsupportedValue can be safely passed cross
// threads.
TEST_F(CrossThreadStyleValueTest, PassUnsupportedValueCrossThread) {
  std::unique_ptr<CrossThreadUnsupportedValue> value =
      std::make_unique<CrossThreadUnsupportedValue>("Unsupported");
  DCHECK(value);

  // Use a Thread to emulate worklet thread.
  thread_ = blink::Thread::CreateThread(
      ThreadCreationParams(ThreadType::kTestThread).SetSupportsGC(true));
  base::WaitableEvent waitable_event;
  PostCrossThreadTask(
      *thread_->GetTaskRunner(), FROM_HERE,
      CrossThreadBindOnce(&CrossThreadStyleValueTest::CheckUnsupportedValue,
                          CrossThreadUnretained(this),
                          CrossThreadUnretained(&waitable_event),
                          std::move(value)));
  waitable_event.Wait();

  ShutDownThread();
}

TEST_F(CrossThreadStyleValueTest, CrossThreadUnsupportedValueToCSSStyleValue) {
  std::unique_ptr<CrossThreadUnsupportedValue> value =
      std::make_unique<CrossThreadUnsupportedValue>("Unsupported");
  DCHECK(value);

  const CSSStyleValue* const style_value = value->ToCSSStyleValue();
  EXPECT_EQ(style_value->GetType(),
            CSSStyleValue::StyleValueType::kUnknownType);
  EXPECT_EQ(style_value->CSSText(), "Unsupported");
}

TEST_F(CrossThreadStyleValueTest, PassUnparsedValueCrossThread) {
  std::unique_ptr<CrossThreadUnparsedValue> value =
      std::make_unique<CrossThreadUnparsedValue>("Unparsed");
  DCHECK(value);

  // Use a Thread to emulate worklet thread.
  thread_ = blink::Thread::CreateThread(
      ThreadCreationParams(ThreadType::kTestThread).SetSupportsGC(true));
  base::WaitableEvent waitable_event;
  PostCrossThreadTask(
      *thread_->GetTaskRunner(), FROM_HERE,
      CrossThreadBindOnce(&CrossThreadStyleValueTest::CheckUnparsedValue,
                          CrossThreadUnretained(this),
                          CrossThreadUnretained(&waitable_event),
                          std::move(value)));
  waitable_event.Wait();

  ShutDownThread();
}

TEST_F(CrossThreadStyleValueTest, CrossThreadUnparsedValueToCSSStyleValue) {
  std::unique_ptr<CrossThreadUnparsedValue> value =
      std::make_unique<CrossThreadUnparsedValue>("Unparsed");
  DCHECK(value);

  CSSStyleValue* style_value = value->ToCSSStyleValue();
  EXPECT_EQ(style_value->GetType(),
            CSSStyleValue::StyleValueType::kUnparsedType);
  EXPECT_EQ(static_cast<CSSUnparsedValue*>(style_value)->ToString(),
            "Unparsed");
}

TEST_F(CrossThreadStyleValueTest, PassKeywordValueCrossThread) {
  std::unique_ptr<CrossThreadKeywordValue> value =
      std::make_unique<CrossThreadKeywordValue>("Keyword");
  DCHECK(value);

  // Use a Thread to emulate worklet thread.
  thread_ = blink::Thread::CreateThread(
      ThreadCreationParams(ThreadType::kTestThread).SetSupportsGC(true));
  base::WaitableEvent waitable_event;
  PostCrossThreadTask(
      *thread_->GetTaskRunner(), FROM_HERE,
      CrossThreadBindOnce(&CrossThreadStyleValueTest::CheckKeywordValue,
                          CrossThreadUnretained(this),
                          CrossThreadUnretained(&waitable_event),
                          std::move(value)));
  waitable_event.Wait();

  ShutDownThread();
}

TEST_F(CrossThreadStyleValueTest, CrossThreadKeywordValueToCSSStyleValue) {
  std::unique_ptr<CrossThreadKeywordValue> value =
      std::make_unique<CrossThreadKeywordValue>("Keyword");
  DCHECK(value);

  CSSStyleValue* style_value = value->ToCSSStyleValue();
  EXPECT_EQ(style_value->GetType(),
            CSSStyleValue::StyleValueType::kKeywordType);
  EXPECT_EQ(static_cast<CSSKeywordValue*>(style_value)->value(), "Keyword");
}

TEST_F(CrossThreadStyleValueTest, PassUnitValueCrossThread) {
  std::unique_ptr<CrossThreadUnitValue> value =
      std::make_unique<CrossThreadUnitValue>(
          1, CSSPrimitiveValue::UnitType::kDegrees);
  DCHECK(value);

  // Use a Thread to emulate worklet thread.
  thread_ = blink::Thread::CreateThread(
      ThreadCreationParams(ThreadType::kTestThread).SetSupportsGC(true));
  base::WaitableEvent waitable_event;
  PostCrossThreadTask(
      *thread_->GetTaskRunner(), FROM_HERE,
      CrossThreadBindOnce(&CrossThreadStyleValueTest::CheckUnitValue,
                          CrossThreadUnretained(this),
                          CrossThreadUnretained(&waitable_event),
                          std::move(value)));
  waitable_event.Wait();

  ShutDownThread();
}

TEST_F(CrossThreadStyleValueTest, CrossThreadUnitValueToCSSStyleValue) {
  std::unique_ptr<CrossThreadUnitValue> value =
      std::make_unique<CrossThreadUnitValue>(
          1, CSSPrimitiveValue::UnitType::kDegrees);
  DCHECK(value);

  CSSStyleValue* style_value = value->ToCSSStyleValue();
  EXPECT_EQ(style_value->GetType(), CSSStyleValue::StyleValueType::kUnitType);
  EXPECT_EQ(static_cast<CSSUnitValue*>(style_value)->value(), 1);
  EXPECT_EQ(static_cast<CSSUnitValue*>(style_value)->unit(), "deg");
}

TEST_F(CrossThreadStyleValueTest, PassColorValueCrossThread) {
  std::unique_ptr<CrossThreadColorValue> value =
      std::make_unique<CrossThreadColorValue>(Color(0, 255, 0));
  DCHECK(value);

  // Use a Thread to emulate worklet thread.
  thread_ = blink::Thread::CreateThread(
      ThreadCreationParams(ThreadType::kTestThread).SetSupportsGC(true));
  base::WaitableEvent waitable_event;
  PostCrossThreadTask(
      *thread_->GetTaskRunner(), FROM_HERE,
      CrossThreadBindOnce(&CrossThreadStyleValueTest::CheckColorValue,
                          CrossThreadUnretained(this),
                          CrossThreadUnretained(&waitable_event),
                          std::move(value)));
  waitable_event.Wait();

  ShutDownThread();
}

TEST_F(CrossThreadStyleValueTest, CrossThreadColorValueToCSSStyleValue) {
  std::unique_ptr<CrossThreadColorValue> value =
      std::make_unique<CrossThreadColorValue>(Color(0, 255, 0));
  DCHECK(value);

  CSSStyleValue* style_value = value->ToCSSStyleValue();
  EXPECT_EQ(style_value->GetType(),
            CSSStyleValue::StyleValueType::kUnsupportedColorType);
  EXPECT_EQ(static_cast<CSSUnsupportedColorValue*>(style_value)->Value(),
            Color(0, 255, 0));
}

TEST_F(CrossThreadStyleValueTest, ComparingNullValues) {
  // Two null values are equal to each other.
  std::unique_ptr<CrossThreadStyleValue> null_value1(nullptr);
  std::unique_ptr<CrossThreadStyleValue> null_value2(nullptr);
  EXPECT_TRUE(DataEquivalent(null_value1, null_value2));

  // If one argument is null and the other isn't they are never equal.
  std::unique_ptr<CrossThreadStyleValue> keyword_value(
      new CrossThreadKeywordValue("keyword"));
  std::unique_ptr<CrossThreadStyleValue> unit_value(
      new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
  std::unique_ptr<CrossThreadStyleValue> unsupported_value(
      new CrossThreadUnsupportedValue("unsupported"));

  EXPECT_FALSE(DataEquivalent(null_value1, keyword_value));
  EXPECT_FALSE(DataEquivalent(null_value1, unit_value));
  EXPECT_FALSE(DataEquivalent(null_value1, unsupported_value));
  EXPECT_FALSE(DataEquivalent(keyword_value, null_value1));
  EXPECT_FALSE(DataEquivalent(unit_value, null_value1));
  EXPECT_FALSE(DataEquivalent(unsupported_value, null_value1));
}

TEST_F(CrossThreadStyleValueTest, ComparingDifferentTypes) {
  // Mismatching types are never equal.
  std::unique_ptr<CrossThreadStyleValue> keyword_value(
      new CrossThreadKeywordValue("keyword"));
  std::unique_ptr<CrossThreadStyleValue> unit_value(
      new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
  std::unique_ptr<CrossThreadStyleValue> unsupported_value(
      new CrossThreadUnsupportedValue("unsupported"));

  EXPECT_FALSE(DataEquivalent(keyword_value, unit_value));
  EXPECT_FALSE(DataEquivalent(keyword_value, unsupported_value));
  EXPECT_FALSE(DataEquivalent(unit_value, unsupported_value));
  EXPECT_FALSE(DataEquivalent(unit_value, keyword_value));
  EXPECT_FALSE(DataEquivalent(unsupported_value, keyword_value));
  EXPECT_FALSE(DataEquivalent(unsupported_value, unit_value));
}

TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadKeywordValue) {
  // CrossThreadKeywordValues are compared on their keyword; if it is equal then
  // so are they.
  std::unique_ptr<CrossThreadStyleValue> keyword_value_1(
      new CrossThreadKeywordValue("keyword"));
  std::unique_ptr<CrossThreadStyleValue> keyword_value_2(
      new CrossThreadKeywordValue("keyword"));
  std::unique_ptr<CrossThreadStyleValue> keyword_value_3(
      new CrossThreadKeywordValue("different"));

  EXPECT_TRUE(DataEquivalent(keyword_value_1, keyword_value_2));
  EXPECT_FALSE(DataEquivalent(keyword_value_1, keyword_value_3));
}

TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadUnitValue) {
  // CrossThreadUnitValues are compared based on their value and unit type; both
  // have to match. There are a lot of unit types; we just test a single sample.
  std::unique_ptr<CrossThreadStyleValue> unit_value_1(
      new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));

  // Same value, same unit.
  std::unique_ptr<CrossThreadStyleValue> unit_value_2(
      new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
  EXPECT_TRUE(DataEquivalent(unit_value_1, unit_value_2));

  // Same value, different unit.
  std::unique_ptr<CrossThreadStyleValue> unit_value_3(
      new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kPoints));
  EXPECT_FALSE(DataEquivalent(unit_value_1, unit_value_3));

  // Different value, same unit.
  std::unique_ptr<CrossThreadStyleValue> unit_value_4(
      new CrossThreadUnitValue(2, CSSPrimitiveValue::UnitType::kDegrees));
  EXPECT_FALSE(DataEquivalent(unit_value_1, unit_value_4));
}

TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadColorValue) {
  // CrossThreadColorValues are compared on their color channel values; all
  // channels must match.
  std::unique_ptr<CrossThreadStyleValue> color_value_1(
      new CrossThreadColorValue(Color(0, 0, 0)));
  std::unique_ptr<CrossThreadStyleValue> color_value_2(
      new CrossThreadColorValue(Color(0, 0, 0)));
  std::unique_ptr<CrossThreadStyleValue> color_value_3(
      new CrossThreadColorValue(Color(0, 255, 0)));

  EXPECT_TRUE(DataEquivalent(color_value_1, color_value_2));
  EXPECT_FALSE(DataEquivalent(color_value_1, color_value_3));
}

TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadUnsupportedValue) {
  // CrossThreadUnsupportedValues are compared on their value; if it is equal
  // then so are they.
  std::unique_ptr<CrossThreadStyleValue> unsupported_value_1(
      new CrossThreadUnsupportedValue("value"));
  std::unique_ptr<CrossThreadStyleValue> unsupported_value_2(
      new CrossThreadUnsupportedValue("value"));
  std::unique_ptr<CrossThreadStyleValue> unsupported_value_3(
      new CrossThreadUnsupportedValue("different"));

  EXPECT_TRUE(DataEquivalent(unsupported_value_1, unsupported_value_2));
  EXPECT_FALSE(DataEquivalent(unsupported_value_1, unsupported_value_3));
}

}  // namespace blink
