// Copyright 2016 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 "core/dom/StyleEngine.h"

#include "core/css/StyleSheetContents.h"
#include "core/dom/Document.h"
#include "core/dom/NodeComputedStyle.h"
#include "core/dom/shadow/ShadowRootInit.h"
#include "core/frame/FrameView.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLStyleElement.h"
#include "core/testing/DummyPageHolder.h"
#include "platform/heap/Heap.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <memory>

namespace blink {

class StyleEngineTest : public ::testing::Test {
 protected:
  void SetUp() override;

  Document& document() { return m_dummyPageHolder->document(); }
  StyleEngine& styleEngine() { return document().styleEngine(); }

  bool isDocumentStyleSheetCollectionClean() {
    return !styleEngine().shouldUpdateDocumentStyleSheetCollection();
  }

  enum RuleSetInvalidation {
    RuleSetInvalidationsScheduled,
    RuleSetInvalidationFullRecalc
  };
  RuleSetInvalidation scheduleInvalidationsForRules(TreeScope&,
                                                    const String& cssText);

 private:
  std::unique_ptr<DummyPageHolder> m_dummyPageHolder;
};

void StyleEngineTest::SetUp() {
  m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
}

StyleEngineTest::RuleSetInvalidation
StyleEngineTest::scheduleInvalidationsForRules(TreeScope& treeScope,
                                               const String& cssText) {
  StyleSheetContents* sheet =
      StyleSheetContents::create(CSSParserContext(HTMLStandardMode, nullptr));
  sheet->parseString(cssText);
  HeapVector<Member<RuleSet>> ruleSets;
  RuleSet& ruleSet = sheet->ensureRuleSet(MediaQueryEvaluator(),
                                          RuleHasDocumentSecurityOrigin);
  ruleSet.compactRulesIfNeeded();
  if (ruleSet.needsFullRecalcForRuleSetInvalidation())
    return RuleSetInvalidationFullRecalc;
  ruleSets.append(&ruleSet);
  styleEngine().scheduleInvalidationsForRuleSets(treeScope, ruleSets);
  return RuleSetInvalidationsScheduled;
}

TEST_F(StyleEngineTest, DocumentDirtyAfterInject) {
  StyleSheetContents* parsedSheet =
      StyleSheetContents::create(CSSParserContext(document(), nullptr));
  parsedSheet->parseString("div {}");
  styleEngine().injectAuthorSheet(parsedSheet);
  document().view()->updateAllLifecyclePhases();

  EXPECT_TRUE(isDocumentStyleSheetCollectionClean());
}

TEST_F(StyleEngineTest, AnalyzedInject) {
  document().body()->setInnerHTML(
      "<style>div { color: red }</style><div id='t1'>Green</div><div></div>");
  document().view()->updateAllLifecyclePhases();

  Element* t1 = document().getElementById("t1");
  ASSERT_TRUE(t1);
  ASSERT_TRUE(t1->computedStyle());
  EXPECT_EQ(makeRGB(255, 0, 0),
            t1->computedStyle()->visitedDependentColor(CSSPropertyColor));

  unsigned beforeCount = styleEngine().styleForElementCount();

  StyleSheetContents* parsedSheet =
      StyleSheetContents::create(CSSParserContext(document(), nullptr));
  parsedSheet->parseString("#t1 { color: green }");
  styleEngine().injectAuthorSheet(parsedSheet);
  document().view()->updateAllLifecyclePhases();

  unsigned afterCount = styleEngine().styleForElementCount();
  EXPECT_EQ(1u, afterCount - beforeCount);

  ASSERT_TRUE(t1->computedStyle());
  EXPECT_EQ(makeRGB(0, 128, 0),
            t1->computedStyle()->visitedDependentColor(CSSPropertyColor));
}

TEST_F(StyleEngineTest, TextToSheetCache) {
  HTMLStyleElement* element = HTMLStyleElement::create(document(), false);

  String sheetText("div {}");
  TextPosition minPos = TextPosition::minimumPosition();
  StyleEngineContext context;

  CSSStyleSheet* sheet1 =
      styleEngine().createSheet(*element, sheetText, minPos, context);

  // Check that the first sheet is not using a cached StyleSheetContents.
  EXPECT_FALSE(sheet1->contents()->isUsedFromTextCache());

  CSSStyleSheet* sheet2 =
      styleEngine().createSheet(*element, sheetText, minPos, context);

  // Check that the second sheet uses the cached StyleSheetContents for the
  // first.
  EXPECT_EQ(sheet1->contents(), sheet2->contents());
  EXPECT_TRUE(sheet2->contents()->isUsedFromTextCache());

  sheet1 = nullptr;
  sheet2 = nullptr;
  element = nullptr;

  // Garbage collection should clear the weak reference in the
  // StyleSheetContents cache.
  ThreadState::current()->collectAllGarbage();

  element = HTMLStyleElement::create(document(), false);
  sheet1 = styleEngine().createSheet(*element, sheetText, minPos, context);

  // Check that we did not use a cached StyleSheetContents after the garbage
  // collection.
  EXPECT_FALSE(sheet1->contents()->isUsedFromTextCache());
}

TEST_F(StyleEngineTest, RuleSetInvalidationTypeSelectors) {
  document().body()->setInnerHTML(
      "<div>"
      "  <span></span>"
      "  <div></div>"
      "</div>");

  document().view()->updateAllLifecyclePhases();

  unsigned beforeCount = styleEngine().styleForElementCount();
  EXPECT_EQ(
      scheduleInvalidationsForRules(document(), "span { background: green}"),
      RuleSetInvalidationsScheduled);
  document().view()->updateAllLifecyclePhases();
  unsigned afterCount = styleEngine().styleForElementCount();
  EXPECT_EQ(1u, afterCount - beforeCount);

  beforeCount = afterCount;
  EXPECT_EQ(scheduleInvalidationsForRules(document(),
                                          "body div { background: green}"),
            RuleSetInvalidationsScheduled);
  document().view()->updateAllLifecyclePhases();
  afterCount = styleEngine().styleForElementCount();
  EXPECT_EQ(2u, afterCount - beforeCount);

  EXPECT_EQ(
      scheduleInvalidationsForRules(document(), "div * { background: green}"),
      RuleSetInvalidationFullRecalc);
}

TEST_F(StyleEngineTest, RuleSetInvalidationHost) {
  document().body()->setInnerHTML("<div id=nohost></div><div id=host></div>");
  Element* host = document().getElementById("host");
  ASSERT_TRUE(host);

  ShadowRootInit init;
  init.setMode("open");
  ShadowRoot* shadowRoot = host->attachShadow(
      ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION);
  ASSERT_TRUE(shadowRoot);

  shadowRoot->setInnerHTML("<div></div><div></div><div></div>");
  document().view()->updateAllLifecyclePhases();

  unsigned beforeCount = styleEngine().styleForElementCount();
  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, ":host(#nohost), #nohost { background: green}"),
            RuleSetInvalidationsScheduled);
  document().view()->updateAllLifecyclePhases();
  unsigned afterCount = styleEngine().styleForElementCount();
  EXPECT_EQ(0u, afterCount - beforeCount);

  beforeCount = afterCount;
  EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot,
                                          ":host(#host) { background: green}"),
            RuleSetInvalidationsScheduled);
  document().view()->updateAllLifecyclePhases();
  afterCount = styleEngine().styleForElementCount();
  EXPECT_EQ(1u, afterCount - beforeCount);

  EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot,
                                          ":host(*) { background: green}"),
            RuleSetInvalidationFullRecalc);
  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, ":host(*) :hover { background: green}"),
            RuleSetInvalidationFullRecalc);
}

TEST_F(StyleEngineTest, RuleSetInvalidationSlotted) {
  document().body()->setInnerHTML(
      "<div id=host>"
      "  <span slot=other class=s1></span>"
      "  <span class=s2></span>"
      "  <span class=s1></span>"
      "  <span></span>"
      "</div>");

  Element* host = document().getElementById("host");
  ASSERT_TRUE(host);

  ShadowRootInit init;
  init.setMode("open");
  ShadowRoot* shadowRoot = host->attachShadow(
      ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION);
  ASSERT_TRUE(shadowRoot);

  shadowRoot->setInnerHTML("<slot name=other></slot><slot></slot>");
  document().view()->updateAllLifecyclePhases();

  unsigned beforeCount = styleEngine().styleForElementCount();
  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, "::slotted(.s1) { background: green}"),
            RuleSetInvalidationsScheduled);
  document().view()->updateAllLifecyclePhases();
  unsigned afterCount = styleEngine().styleForElementCount();
  EXPECT_EQ(4u, afterCount - beforeCount);

  beforeCount = afterCount;
  EXPECT_EQ(scheduleInvalidationsForRules(*shadowRoot,
                                          "::slotted(*) { background: green}"),
            RuleSetInvalidationsScheduled);
  document().view()->updateAllLifecyclePhases();
  afterCount = styleEngine().styleForElementCount();
  EXPECT_EQ(4u, afterCount - beforeCount);
}

TEST_F(StyleEngineTest, RuleSetInvalidationHostContext) {
  document().body()->setInnerHTML("<div id=host></div>");
  Element* host = document().getElementById("host");
  ASSERT_TRUE(host);

  ShadowRootInit init;
  init.setMode("open");
  ShadowRoot* shadowRoot = host->attachShadow(
      ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION);
  ASSERT_TRUE(shadowRoot);

  shadowRoot->setInnerHTML("<div></div><div class=a></div><div></div>");
  document().view()->updateAllLifecyclePhases();

  unsigned beforeCount = styleEngine().styleForElementCount();
  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, ":host-context(.nomatch) .a { background: green}"),
            RuleSetInvalidationsScheduled);
  document().view()->updateAllLifecyclePhases();
  unsigned afterCount = styleEngine().styleForElementCount();
  EXPECT_EQ(1u, afterCount - beforeCount);

  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, ":host-context(:hover) { background: green}"),
            RuleSetInvalidationFullRecalc);
  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, ":host-context(#host) { background: green}"),
            RuleSetInvalidationFullRecalc);
}

TEST_F(StyleEngineTest, RuleSetInvalidationV0BoundaryCrossing) {
  document().body()->setInnerHTML("<div id=host></div>");
  Element* host = document().getElementById("host");
  ASSERT_TRUE(host);

  ShadowRootInit init;
  init.setMode("open");
  ShadowRoot* shadowRoot = host->attachShadow(
      ScriptState::forMainWorld(document().frame()), init, ASSERT_NO_EXCEPTION);
  ASSERT_TRUE(shadowRoot);

  shadowRoot->setInnerHTML("<div></div><div class=a></div><div></div>");
  document().view()->updateAllLifecyclePhases();

  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, ".a ::content span { background: green}"),
            RuleSetInvalidationFullRecalc);
  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, ".a /deep/ span { background: green}"),
            RuleSetInvalidationFullRecalc);
  EXPECT_EQ(scheduleInvalidationsForRules(
                *shadowRoot, ".a::shadow span { background: green}"),
            RuleSetInvalidationFullRecalc);
}

TEST_F(StyleEngineTest, HasViewportDependentMediaQueries) {
  document().body()->setInnerHTML(
      "<style>div {}</style>"
      "<style id='sheet' media='(min-width: 200px)'>"
      "  div {}"
      "</style>");

  Element* styleElement = document().getElementById("sheet");

  for (unsigned i = 0; i < 10; i++) {
    document().body()->removeChild(styleElement);
    document().view()->updateAllLifecyclePhases();
    document().body()->appendChild(styleElement);
    document().view()->updateAllLifecyclePhases();
  }

  EXPECT_TRUE(document().styleEngine().hasViewportDependentMediaQueries());

  document().body()->removeChild(styleElement);
  document().view()->updateAllLifecyclePhases();

  EXPECT_FALSE(document().styleEngine().hasViewportDependentMediaQueries());
}

}  // namespace blink
