// Copyright 2018 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 "components/ui_devtools/css_agent.h"

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/test/task_environment.h"
#include "components/ui_devtools/agent_util.h"
#include "components/ui_devtools/dom_agent.h"
#include "components/ui_devtools/ui_devtools_unittest_utils.h"
#include "components/ui_devtools/ui_element.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ui_devtools {

class FakeUIElement : public UIElement {
 public:
  FakeUIElement(UIElementDelegate* ui_element_delegate)
      : UIElement(UIElementType::ROOT, ui_element_delegate, nullptr) {}

  ~FakeUIElement() override {}
  void GetBounds(gfx::Rect* bounds) const override { *bounds = bounds_; }
  void SetBounds(const gfx::Rect& bounds) override { bounds_ = bounds; }
  void GetVisible(bool* visible) const override { *visible = visible_; }
  void SetVisible(bool visible) override { visible_ = visible; }
  std::vector<std::string> GetAttributes() const override { return {}; }
  std::pair<gfx::NativeWindow, gfx::Rect> GetNodeWindowAndScreenBounds()
      const override {
    return {};
  }
  bool visible() const { return visible_; }
  gfx::Rect bounds() const { return bounds_; }
  void AddSource(std::string path, int line) {
    UIElement::AddSource(path, line);
  }

 private:
  gfx::Rect bounds_;
  bool visible_;
};

class FakeDOMAgent : public DOMAgent {
 public:
  void OnUIElementAdded(UIElement* parent, UIElement* child) override {
    // nullptr root short circuits everything but adding |child|
    // to the node ID map, which is all we need here.
    DOMAgent::OnUIElementAdded(nullptr, child);
  }

  std::unique_ptr<protocol::DOM::Node> BuildTreeForUIElement(
      UIElement* root) override {
    return BuildDomNodeFromUIElement(root);
  }

  std::vector<UIElement*> CreateChildrenForRoot() override { return {}; }
};

class CSSAgentTest : public testing::Test {
 public:
  void SetUp() override {
    testing::Test::SetUp();
    frontend_channel_ = std::make_unique<FakeFrontendChannel>();
    uber_dispatcher_ =
        std::make_unique<protocol::UberDispatcher>(frontend_channel_.get());
    dom_agent_ = std::make_unique<FakeDOMAgent>();
    dom_agent_->Init(uber_dispatcher_.get());
    css_agent_ = std::make_unique<CSSAgent>(dom_agent_.get());
    css_agent_->Init(uber_dispatcher_.get());
    css_agent_->enable();
    element_ = std::make_unique<FakeUIElement>(dom_agent_.get());
    element()->SetBaseStylesheetId(0);
    dom_agent_->OnUIElementAdded(nullptr, element_.get());
  }

  void TearDown() override {
    css_agent_.reset();
    dom_agent_.reset();
    uber_dispatcher_.reset();
    frontend_channel_.reset();
    element_.reset();
    testing::Test::TearDown();
  }

  std::string BuildStylesheetUId(int node_id, int stylesheet_id) {
    return base::NumberToString(node_id) + "_" +
           base::NumberToString(stylesheet_id);
  }

 protected:
  base::test::TaskEnvironment task_environment_;
  using StyleArray = protocol::Array<protocol::CSS::CSSStyle>;

  std::pair<bool, std::unique_ptr<StyleArray>>
  SetStyle(const std::string& style_text, int node_id, int stylesheet_id = 0) {
    auto edits = std::make_unique<
        protocol::Array<protocol::CSS::StyleDeclarationEdit>>();
    auto edit = protocol::CSS::StyleDeclarationEdit::create()
                    .setStyleSheetId(BuildStylesheetUId(node_id, stylesheet_id))
                    .setRange(protocol::CSS::SourceRange::create()
                                  .setStartLine(0)
                                  .setStartColumn(0)
                                  .setEndLine(0)
                                  .setEndColumn(0)
                                  .build())
                    .setText(style_text)
                    .build();
    edits->emplace_back(std::move(edit));
    std::unique_ptr<StyleArray> output;
    auto response = css_agent_->setStyleTexts(std::move(edits), &output);
    return {response.IsSuccess(), std::move(output)};
  }

  std::string GetValueForProperty(protocol::CSS::CSSStyle* style,
                                  const std::string& property_name) {
    for (const auto& property : *(style->getCssProperties())) {
      if (property->getName() == property_name) {
        return property->getValue();
      }
    }
    return std::string();
  }

  int GetStyleSheetChangedCount(std::string stylesheet_id) {
    return frontend_channel_->CountProtocolNotificationMessage(
        "{\"method\":\"CSS.styleSheetChanged\",\"params\":{"
        "\"styleSheetId\":\"" +
        stylesheet_id + "\"}}");
  }

  std::pair<bool, std::string> GetSourceForElement() {
    std::string output;
    auto response = css_agent_->getStyleSheetText(
        BuildStylesheetUId(element()->node_id(), 0), &output);
    return {response.IsSuccess(), output};
  }

  CSSAgent* css_agent() { return css_agent_.get(); }
  DOMAgent* dom_agent() { return dom_agent_.get(); }
  FakeUIElement* element() { return element_.get(); }

 private:
  std::unique_ptr<CSSAgent> css_agent_;
  std::unique_ptr<DOMAgent> dom_agent_;
  std::unique_ptr<FakeFrontendChannel> frontend_channel_;
  std::unique_ptr<protocol::UberDispatcher> uber_dispatcher_;
  std::unique_ptr<FakeUIElement> element_;
};

TEST_F(CSSAgentTest, UnrecognizedNodeFails) {
  EXPECT_FALSE(SetStyle("x : 25", 42).first);
}

TEST_F(CSSAgentTest, UnrecognizedKeyFails) {
  element()->SetVisible(true);
  element()->SetBounds(gfx::Rect(1, 2, 3, 4));

  auto result = SetStyle("nonsense : 3.14", element()->node_id());

  EXPECT_FALSE(result.first);
  EXPECT_FALSE(result.second);
  // Ensure element didn't change.
  EXPECT_TRUE(element()->visible());
  EXPECT_EQ(element()->bounds(), gfx::Rect(1, 2, 3, 4));
}

TEST_F(CSSAgentTest, UnrecognizedValueFails) {
  element()->SetVisible(true);
  element()->SetBounds(gfx::Rect(1, 2, 3, 4));

  auto result = SetStyle("visibility : banana", element()->node_id());
  EXPECT_FALSE(result.first);
  EXPECT_FALSE(result.second);
  // Ensure element didn't change.
  EXPECT_TRUE(element()->visible());
  EXPECT_EQ(element()->bounds(), gfx::Rect(1, 2, 3, 4));
}

TEST_F(CSSAgentTest, BadInputsFail) {
  element()->SetVisible(true);
  element()->SetBounds(gfx::Rect(1, 2, 3, 4));

  // Input with no property name.
  auto result = SetStyle(": 1;", element()->node_id());
  EXPECT_FALSE(result.first);
  EXPECT_FALSE(result.second);
  // Ensure element didn't change.
  EXPECT_TRUE(element()->visible());
  EXPECT_EQ(element()->bounds(), gfx::Rect(1, 2, 3, 4));

  // Input with no property value.
  result = SetStyle("visibility:", element()->node_id());
  EXPECT_FALSE(result.first);
  EXPECT_FALSE(result.second);
  // Ensure element didn't change.
  EXPECT_TRUE(element()->visible());
  EXPECT_EQ(element()->bounds(), gfx::Rect(1, 2, 3, 4));

  // Blank input.
  result = SetStyle(":", element()->node_id());
  EXPECT_FALSE(result.first);
  EXPECT_FALSE(result.second);
  // Ensure element didn't change.
  EXPECT_TRUE(element()->visible());
  EXPECT_EQ(element()->bounds(), gfx::Rect(1, 2, 3, 4));
}

TEST_F(CSSAgentTest, SettingVisibility) {
  element()->SetVisible(false);
  DCHECK(!element()->visible());

  auto result = SetStyle("visibility: 1", element()->node_id());
  EXPECT_TRUE(result.first);
  EXPECT_TRUE(element()->visible());

  EXPECT_EQ(result.second->size(), 1U);
  std::unique_ptr<protocol::CSS::CSSStyle>& style = result.second->at(0);
  EXPECT_EQ(style->getStyleSheetId("default"),
            base::NumberToString(element()->node_id()) + "_0");
  EXPECT_EQ(GetValueForProperty(style.get(), "visibility"), "true");
}

TEST_F(CSSAgentTest, SettingX) {
  DCHECK_EQ(element()->bounds().x(), 0);

  auto result = SetStyle("x: 500", element()->node_id());
  EXPECT_TRUE(result.first);
  EXPECT_EQ(element()->bounds().x(), 500);
  EXPECT_EQ(result.second->size(), 1U);
  std::unique_ptr<protocol::CSS::CSSStyle>& style = result.second->at(0);
  EXPECT_EQ(style->getStyleSheetId("default"),
            base::NumberToString(element()->node_id()) + "_0");
  EXPECT_EQ(GetValueForProperty(style.get(), "x"), "500");
}

TEST_F(CSSAgentTest, SettingY) {
  DCHECK_EQ(element()->bounds().y(), 0);

  auto result = SetStyle("y: 100", element()->node_id());
  EXPECT_TRUE(result.first);
  EXPECT_EQ(element()->bounds().y(), 100);
  EXPECT_EQ(result.second->size(), 1U);
  std::unique_ptr<protocol::CSS::CSSStyle>& style = result.second->at(0);
  EXPECT_EQ(style->getStyleSheetId("default"),
            base::NumberToString(element()->node_id()) + "_0");
  EXPECT_EQ(GetValueForProperty(style.get(), "y"), "100");
}
TEST_F(CSSAgentTest, SettingWidth) {
  DCHECK_EQ(element()->bounds().width(), 0);

  auto result = SetStyle("width: 20", element()->node_id());
  EXPECT_TRUE(result.first);
  EXPECT_EQ(element()->bounds().width(), 20);
  EXPECT_EQ(result.second->size(), 1U);
  std::unique_ptr<protocol::CSS::CSSStyle>& style = result.second->at(0);
  EXPECT_EQ(style->getStyleSheetId("default"),
            base::NumberToString(element()->node_id()) + "_0");
  EXPECT_EQ(GetValueForProperty(style.get(), "width"), "20");
}
TEST_F(CSSAgentTest, SettingHeight) {
  DCHECK_EQ(element()->bounds().height(), 0);

  auto result = SetStyle("height: 30", element()->node_id());
  EXPECT_TRUE(result.first);
  EXPECT_EQ(element()->bounds().height(), 30);
  EXPECT_EQ(result.second->size(), 1U);
  std::unique_ptr<protocol::CSS::CSSStyle>& style = result.second->at(0);
  EXPECT_EQ(style->getStyleSheetId("default"),
            base::NumberToString(element()->node_id()) + "_0");
  EXPECT_EQ(GetValueForProperty(style.get(), "height"), "30");
}

TEST_F(CSSAgentTest, SettingAll) {
  DCHECK(element()->bounds() == gfx::Rect());
  element()->SetVisible(true);
  DCHECK(element()->visible());

  // Throw in odd whitespace while we're at it.
  std::string new_text(
      "\ny: 25; width: 50;   visibility:0; height: 30;\nx: 9000;\n\n");
  auto result = SetStyle(new_text, element()->node_id());
  EXPECT_TRUE(result.first);
  EXPECT_EQ(element()->bounds(), gfx::Rect(9000, 25, 50, 30));
  EXPECT_FALSE(element()->visible());
  EXPECT_EQ(result.second->size(), 1U);
  std::unique_ptr<protocol::CSS::CSSStyle>& style = result.second->at(0);
  EXPECT_EQ(style->getStyleSheetId("default"),
            base::NumberToString(element()->node_id()) + "_0");
  EXPECT_EQ(GetValueForProperty(style.get(), "x"), "9000");
  EXPECT_EQ(GetValueForProperty(style.get(), "y"), "25");
  EXPECT_EQ(GetValueForProperty(style.get(), "width"), "50");
  EXPECT_EQ(GetValueForProperty(style.get(), "height"), "30");
  EXPECT_EQ(GetValueForProperty(style.get(), "visibility"), "false");
}

TEST_F(CSSAgentTest, UpdateOnBoundsChange) {
  FakeUIElement another_element(dom_agent());
  another_element.SetBaseStylesheetId(0);
  std::string element_stylesheet_id =
      BuildStylesheetUId(element()->node_id(), 0);
  std::string another_element_stylesheet_id =
      BuildStylesheetUId(another_element.node_id(), 0);

  EXPECT_EQ(0, GetStyleSheetChangedCount(element_stylesheet_id));
  EXPECT_EQ(0, GetStyleSheetChangedCount(another_element_stylesheet_id));
  css_agent()->OnElementBoundsChanged(element());
  EXPECT_EQ(1, GetStyleSheetChangedCount(element_stylesheet_id));
  EXPECT_EQ(0, GetStyleSheetChangedCount(another_element_stylesheet_id));
  css_agent()->OnElementBoundsChanged(&another_element);
  EXPECT_EQ(1, GetStyleSheetChangedCount(element_stylesheet_id));
  EXPECT_EQ(1, GetStyleSheetChangedCount(another_element_stylesheet_id));

  css_agent()->OnElementBoundsChanged(&another_element);
  EXPECT_EQ(1, GetStyleSheetChangedCount(element_stylesheet_id));
  EXPECT_EQ(2, GetStyleSheetChangedCount(another_element_stylesheet_id));
}

TEST_F(CSSAgentTest, GetSource) {
  // Tests CSSAgent::getStyleSheetText() with one source file.
  std::string file = "components/test/data/ui_devtools/test_file.cc";
  element()->AddSource(file, 0);
  auto result = GetSourceForElement();

  // Ensure that test_file.cc was read in correctly.
  EXPECT_TRUE(result.first);
  EXPECT_NE(std::string::npos,
            result.second.find("This file is for testing GetSource."));
}

TEST_F(CSSAgentTest, BadPathFails) {
  element()->AddSource("not/a/real/path", 0);
  auto result = GetSourceForElement();

  EXPECT_FALSE(result.first);
  EXPECT_EQ(result.second, "");
}

}  // namespace ui_devtools
