// Copyright 2020 The Cobalt Authors. 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/percentage_value.h"
#include "cobalt/cssom/testing/mock_css_parser.h"  // nogncheck
#include "cobalt/dom/document.h"
#include "cobalt/dom/dom_stat_tracker.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/testing/fake_exception_state.h"
#include "cobalt/dom/testing/mock_layout_boxes.h"
#include "cobalt/dom/testing/stub_environment_settings.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using cobalt::cssom::PercentageValue;
using cobalt::cssom::PropertyListValue;
using cobalt::dom::testing::MockLayoutBoxes;
using ::testing::NiceMock;
using ::testing::_;
using ::testing::Return;

namespace cobalt {
namespace dom {

class MockDocumentObserver : public DocumentObserver {
 public:
  MOCK_METHOD0(OnLoad, void());

  MOCK_METHOD0(OnMutation, void());

  MOCK_METHOD0(OnFocusChanged, void());
};

class IntersectionCallbackMock {
 public:
  MOCK_METHOD2(
      NativeIntersectionObserverCallback,
      void(const IntersectionObserver::IntersectionObserverEntrySequence&,
           const scoped_refptr<IntersectionObserver>&));
};

class IntersectionObserverTest : public ::testing::Test {
 protected:
  IntersectionObserverTest()
      : dom_stat_tracker_(new DomStatTracker("IntersectionObserverTest")),
        html_element_context_(&environment_settings_, NULL, NULL, &css_parser_,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, dom_stat_tracker_.get(),
                              "", base::kApplicationStateStarted, NULL, NULL),
        document_(new Document(&html_element_context_)) {}

  scoped_refptr<Document> document() { return document_; }
  scoped_refptr<IntersectionObserver> CreateIntersectionObserver();
  void CreateDocumentWithTwoChildrenAndMockLayoutBoxes();

 private:
  std::unique_ptr<DomStatTracker> dom_stat_tracker_;
  testing::StubEnvironmentSettings environment_settings_;
  NiceMock<cssom::testing::MockCSSParser> css_parser_;
  testing::FakeExceptionState exception_state_;
  HTMLElementContext html_element_context_;
  scoped_refptr<Document> document_;
  IntersectionCallbackMock callback_mock_;
};

scoped_refptr<IntersectionObserver>
IntersectionObserverTest::CreateIntersectionObserver() {
  // The intersection observer constructor will use the mock css parser to parse
  // the root margin property value. Because "ParsePropertyValue()"" returns a
  // "PropertyValue", which is not a built-in type, we must set a default
  // action and return type here.
  std::unique_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());
  builder->push_back(new PercentageValue(0.0f));
  scoped_refptr<PropertyListValue> property_list_value =
      new PropertyListValue(std::move(builder));
  ON_CALL(css_parser_, ParsePropertyValue(_, _, _))
      .WillByDefault(Return(property_list_value));

  return new IntersectionObserver(
      document_, &css_parser_,
      base::Bind(&IntersectionCallbackMock::NativeIntersectionObserverCallback,
                 base::Unretained(&callback_mock_)),
      &exception_state_);
}

void IntersectionObserverTest::
    CreateDocumentWithTwoChildrenAndMockLayoutBoxes() {
  scoped_refptr<HTMLElement> first_child_element_ =
      document_->CreateElement("div")->AsHTMLElement();
  document_->AppendChild(first_child_element_);

  scoped_refptr<HTMLElement> second_child_element_ =
      document_->CreateElement("div")->AsHTMLElement();
  first_child_element_->AppendChild(second_child_element_);

  std::unique_ptr<MockLayoutBoxes> layout_boxes(new MockLayoutBoxes);
  document_->document_element()->AsHTMLElement()->set_layout_boxes(
      std::unique_ptr<LayoutBoxes>(layout_boxes.release()));
}

TEST_F(IntersectionObserverTest, RegisterIntersectionObserverForTarget) {
  CreateDocumentWithTwoChildrenAndMockLayoutBoxes();

  NiceMock<MockDocumentObserver> document_observer;
  document()->AddObserver(&document_observer);

  std::unique_ptr<ElementIntersectionObserverModule>
      element_intersection_observer_module =
          std::make_unique<ElementIntersectionObserverModule>(
              document()->last_element_child());

  // Treat the second child element as an intersection observer target
  // (the first child element is the same as the document element).
  // When the observer is registered, it should record a mutation on the
  // document and invalidate the layout boxes up to the document element.
  EXPECT_NE(document()->document_element()->AsHTMLElement()->layout_boxes(),
            nullptr);
  EXPECT_CALL(document_observer, OnMutation()).Times(1);
  scoped_refptr<IntersectionObserver> intersection_observer =
      CreateIntersectionObserver();
  element_intersection_observer_module->RegisterIntersectionObserverForTarget(
      intersection_observer);
  EXPECT_EQ(document()->document_element()->AsHTMLElement()->layout_boxes(),
            nullptr);
}

}  // namespace dom
}  // namespace cobalt
