// Copyright 2017 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 "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/mutation_observer_init.h"
#include "cobalt/dom/mutation_observer_task_manager.h"
#include "cobalt/dom/mutation_record.h"
#include "cobalt/dom/mutation_reporter.h"
#include "cobalt/dom/node_list.h"
#include "cobalt/dom/text.h"
#include "cobalt/script/sequence.h"
#include "cobalt/script/testing/mock_exception_state.h"
#include "cobalt/test/empty_document.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::SaveArg;

namespace cobalt {
namespace dom {
// Helper struct for childList mutations.
struct ChildListMutationArguments {
  scoped_refptr<dom::Element> previous_sibling;
  scoped_refptr<dom::Element> next_sibling;
  scoped_refptr<dom::NodeList> added_nodes;
  scoped_refptr<dom::NodeList> removed_nodes;
};

class MutationCallbackMock {
 public:
  MOCK_METHOD2(NativeMutationCallback,
               void(const MutationObserver::MutationRecordSequence&,
                    const scoped_refptr<MutationObserver>&));
};

class MutationObserverTest : public ::testing::Test {
 protected:
  dom::Document* document() { return empty_document_.document(); }
  MutationObserverTaskManager* task_manager() { return &task_manager_; }
  MutationCallbackMock* callback_mock() { return &callback_mock_; }

  scoped_refptr<Element> CreateDiv() {
    scoped_refptr<Element> element = document()->CreateElement("div");
    DCHECK(element);
    document()->AppendChild(element);
    return element;
  }

  scoped_refptr<MutationObserver> CreateObserver() {
    return new MutationObserver(
        base::Bind(&MutationCallbackMock::NativeMutationCallback,
                   base::Unretained(&callback_mock_)),
        &task_manager_);
  }

  ChildListMutationArguments CreateChildListMutationArguments() {
    // These nodes are not actually related in the way they are named
    // (next_sibling, previous_sibling, etc) but that is not relevant for the
    // purpose of these tests.
    ChildListMutationArguments args;
    args.previous_sibling = CreateDiv();
    args.next_sibling = CreateDiv();
    args.added_nodes = new NodeList();
    args.added_nodes->AppendNode(CreateDiv());
    args.removed_nodes = new NodeList();
    args.removed_nodes->AppendNode(CreateDiv());
    return args;
  }

 private:
  MutationObserverTaskManager task_manager_;
  test::EmptyDocument empty_document_;
  MutationCallbackMock callback_mock_;
  MessageLoop message_loop_;
};

TEST_F(MutationObserverTest, CreateAttributeMutationRecord) {
  scoped_refptr<dom::Element> target = CreateDiv();
  scoped_refptr<MutationRecord> record =
      MutationRecord::CreateAttributeMutationRecord(target, "attribute_name",
                                                    std::string("old_value"));
  ASSERT_TRUE(record);

  // "type" and attribute-related attributes are set as expected
  EXPECT_STREQ("attributes", record->type().c_str());
  EXPECT_TRUE(record->attribute_name());
  EXPECT_STREQ("attribute_name", record->attribute_name()->c_str());
  EXPECT_TRUE(record->old_value());
  EXPECT_STREQ("old_value", record->old_value()->c_str());

  // "target" is set as expected.
  EXPECT_EQ(target, record->target());

  // Namespaces are not supported.
  EXPECT_FALSE(record->attribute_namespace());

  // Unrelated attributes are not set.
  ASSERT_TRUE(record->added_nodes());
  EXPECT_EQ(record->added_nodes()->length(), 0);
  ASSERT_TRUE(record->removed_nodes());
  EXPECT_EQ(record->removed_nodes()->length(), 0);
  EXPECT_FALSE(record->previous_sibling());
  EXPECT_FALSE(record->next_sibling());
}

TEST_F(MutationObserverTest, CreateCharacterDataMutationRecord) {
  scoped_refptr<dom::Element> target = CreateDiv();
  scoped_refptr<MutationRecord> record =
      MutationRecord::CreateCharacterDataMutationRecord(
          target, std::string("old_character_data"));
  ASSERT_TRUE(record);

  // "type" and attribute-related attributes are set as expected
  EXPECT_STREQ("characterData", record->type().c_str());
  EXPECT_TRUE(record->old_value());
  EXPECT_STREQ("old_character_data", record->old_value()->c_str());

  // "target" is set as expected.
  EXPECT_EQ(target, record->target());

  // Unrelated attributes are not set.
  EXPECT_FALSE(record->attribute_name());
  EXPECT_FALSE(record->attribute_namespace());
  ASSERT_TRUE(record->added_nodes());
  EXPECT_EQ(record->added_nodes()->length(), 0);
  ASSERT_TRUE(record->removed_nodes());
  EXPECT_EQ(record->removed_nodes()->length(), 0);
  EXPECT_FALSE(record->previous_sibling());
  EXPECT_FALSE(record->next_sibling());
}

TEST_F(MutationObserverTest, CreateChildListMutationRecord) {
  scoped_refptr<dom::Element> target = CreateDiv();

  ChildListMutationArguments args = CreateChildListMutationArguments();
  scoped_refptr<MutationRecord> record =
      MutationRecord::CreateChildListMutationRecord(
          target, args.added_nodes, args.removed_nodes, args.previous_sibling,
          args.next_sibling);
  ASSERT_TRUE(record);

  // "type" and attribute-related attributes are set as expected
  EXPECT_STREQ("childList", record->type().c_str());
  EXPECT_EQ(args.added_nodes, record->added_nodes());
  EXPECT_EQ(args.removed_nodes, record->removed_nodes());
  EXPECT_EQ(args.previous_sibling, record->previous_sibling());
  EXPECT_EQ(args.next_sibling, record->next_sibling());

  // "target" is set as expected.
  EXPECT_EQ(target, record->target());

  // Unrelated attributes are not set.
  EXPECT_FALSE(record->attribute_name());
  EXPECT_FALSE(record->attribute_namespace());
  EXPECT_FALSE(record->old_value());
}

TEST_F(MutationObserverTest, MutationObserverInit) {
  MutationObserverInit init;
  // Default values are set according to spec.
  EXPECT_FALSE(init.child_list());
  EXPECT_FALSE(init.subtree());

  // Other values are not set.
  EXPECT_FALSE(init.has_attributes());
  EXPECT_FALSE(init.has_character_data());
  EXPECT_FALSE(init.has_attribute_old_value());
  EXPECT_FALSE(init.has_character_data_old_value());
  EXPECT_FALSE(init.has_attribute_filter());

  // Set other values.
  init.set_attributes(true);
  init.set_character_data(true);
  init.set_attribute_old_value(true);
  init.set_character_data_old_value(true);
  script::Sequence<std::string> attribute_filter;
  attribute_filter.push_back("a_filter");
  init.set_attribute_filter(attribute_filter);

  // Other values are now set.
  EXPECT_TRUE(init.has_attributes());
  EXPECT_TRUE(init.attributes());
  EXPECT_TRUE(init.has_character_data());
  EXPECT_TRUE(init.character_data());
  EXPECT_TRUE(init.has_attribute_old_value());
  EXPECT_TRUE(init.attribute_old_value());
  EXPECT_TRUE(init.has_character_data_old_value());
  EXPECT_TRUE(init.character_data_old_value());
  EXPECT_TRUE(init.has_attribute_filter());
  EXPECT_EQ(init.attribute_filter().size(), attribute_filter.size());
  EXPECT_EQ(init.attribute_filter().at(0), attribute_filter.at(0));
}

TEST_F(MutationObserverTest, TakeRecords) {
  scoped_refptr<dom::Element> target = CreateDiv();

  // Newly created observer shouldn't have records.
  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserver::MutationRecordSequence records;
  records = observer->TakeRecords();
  EXPECT_TRUE(records.empty());

  // Append a mutation records.
  scoped_refptr<MutationRecord> record =
      MutationRecord::CreateCharacterDataMutationRecord(
          target, std::string("old_character_data"));
  observer->QueueMutationRecord(record);

  // The queued record can be taken once.
  records = observer->TakeRecords();
  ASSERT_EQ(1, records.size());
  ASSERT_EQ(records.at(0), record);
  records = observer->TakeRecords();
  EXPECT_TRUE(records.empty());
}

TEST_F(MutationObserverTest, Notify) {
  scoped_refptr<dom::Element> target = CreateDiv();

  // Create a new observer and queue a mutation record.
  scoped_refptr<MutationObserver> observer = CreateObserver();
  scoped_refptr<MutationRecord> record =
      MutationRecord::CreateCharacterDataMutationRecord(
          target, std::string("old_character_data"));
  observer->QueueMutationRecord(record);

  // Callback should be fired with the first argument being a sequence of the
  // queued record, and the second argument being the observer.
  MutationObserver::MutationRecordSequence records;
  EXPECT_CALL(*callback_mock(), NativeMutationCallback(_, observer))
      .WillOnce(SaveArg<0>(&records));
  observer->Notify();
  ASSERT_EQ(1, records.size());
  EXPECT_EQ(record, records.at(0));

  // There should be no more records queued up after the callback has been
  // fired.
  records = observer->TakeRecords();
  EXPECT_TRUE(records.empty());
}

TEST_F(MutationObserverTest, ReportMutation) {
  scoped_refptr<dom::Element> target = CreateDiv();
  // Create a registered observer that cares about attribute and character data
  // mutations.
  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit init;
  init.set_attributes(true);
  init.set_child_list(false);
  init.set_character_data(true);

  // Create a MutationReporter for the list of registered observers.
  scoped_ptr<std::vector<RegisteredObserver> > registered_observers(
      new std::vector<RegisteredObserver>());
  registered_observers->push_back(
      RegisteredObserver(target.get(), observer, init));
  MutationReporter reporter(target.get(), registered_observers.Pass());

  // Report a few mutations.
  reporter.ReportAttributesMutation("attribute_name", std::string("old_value"));
  reporter.ReportCharacterDataMutation("old_character_data");
  ChildListMutationArguments args = CreateChildListMutationArguments();
  reporter.ReportChildListMutation(args.added_nodes, args.removed_nodes,
                                   args.previous_sibling, args.next_sibling);

  // Check that mutation records for the mutation types we care about have
  // been queued.
  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  ASSERT_EQ(2, records.size());
  EXPECT_EQ(records.at(0)->type(), "attributes");
  EXPECT_EQ(records.at(1)->type(), "characterData");
}

TEST_F(MutationObserverTest, AttributeFilter) {
  scoped_refptr<dom::Element> target = CreateDiv();
  // Create a registered observer that cares about attribute and character data
  // mutations.
  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit init;
  script::Sequence<std::string> attribute_filter;
  attribute_filter.push_back("banana");
  attribute_filter.push_back("potato");
  init.set_attribute_filter(attribute_filter);
  init.set_attributes(true);

  // Create a MutationReporter for the list of registered observers.
  scoped_ptr<std::vector<RegisteredObserver> > registered_observers(
      new std::vector<RegisteredObserver>());
  registered_observers->push_back(
      RegisteredObserver(target.get(), observer, init));
  MutationReporter reporter(target.get(), registered_observers.Pass());

  // Report a few attribute mutations.
  reporter.ReportAttributesMutation("banana", std::string("rotten"));
  reporter.ReportAttributesMutation("apple", std::string("wormy"));
  reporter.ReportAttributesMutation("potato", std::string("mashed"));

  // Check that mutation records for the filtered attrbiutes have been queued.
  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  ASSERT_EQ(2, records.size());
  EXPECT_STREQ(records.at(0)->attribute_name()->c_str(), "banana");
  EXPECT_STREQ(records.at(1)->attribute_name()->c_str(), "potato");
}

TEST_F(MutationObserverTest, RegisteredObserverList) {
  scoped_refptr<dom::Element> target = CreateDiv();
  scoped_refptr<MutationObserver> observer = CreateObserver();

  RegisteredObserverList observer_list(target.get());

  // Add an observer with options.
  MutationObserverInit options;
  options.set_attributes(true);
  EXPECT_TRUE(observer_list.AddMutationObserver(observer, options));
  EXPECT_EQ(1, observer_list.registered_observers().size());
  EXPECT_EQ(observer, observer_list.registered_observers()[0].observer());
  EXPECT_TRUE(observer_list.registered_observers()[0].options().attributes());
  EXPECT_FALSE(
      observer_list.registered_observers()[0].options().has_character_data());
  EXPECT_FALSE(observer_list.registered_observers()[0].options().child_list());

  // Adding the same observer updates the options.
  options = MutationObserverInit();
  options.set_child_list(true);
  EXPECT_TRUE(observer_list.AddMutationObserver(observer, options));
  EXPECT_EQ(1, observer_list.registered_observers().size());
  EXPECT_EQ(observer, observer_list.registered_observers()[0].observer());
  EXPECT_FALSE(
      observer_list.registered_observers()[0].options().has_attributes());
  EXPECT_FALSE(
      observer_list.registered_observers()[0].options().has_character_data());
  EXPECT_TRUE(observer_list.registered_observers()[0].options().child_list());

  // Remove the observer.
  observer_list.RemoveMutationObserver(observer);
  EXPECT_EQ(0, observer_list.registered_observers().size());
}

TEST_F(MutationObserverTest, LazilySetOptions) {
  scoped_refptr<dom::Element> target = CreateDiv();
  scoped_refptr<MutationObserver> observer = CreateObserver();

  RegisteredObserverList observer_list(target.get());

  // |attributes| gets set if an attribute-related option is set.
  MutationObserverInit options;
  options.set_attribute_old_value(true);
  EXPECT_TRUE(observer_list.AddMutationObserver(observer, options));
  EXPECT_EQ(1, observer_list.registered_observers().size());
  EXPECT_TRUE(observer_list.registered_observers()[0].options().attributes());

  // |character_data| gets set if an attribute-related option is set.
  options = MutationObserverInit();
  options.set_character_data_old_value(true);
  EXPECT_TRUE(observer_list.AddMutationObserver(observer, options));
  EXPECT_EQ(1, observer_list.registered_observers().size());
  EXPECT_TRUE(
      observer_list.registered_observers()[0].options().character_data());
}

TEST_F(MutationObserverTest, InvalidOptions) {
  scoped_refptr<dom::Element> target = CreateDiv();
  scoped_refptr<MutationObserver> observer = CreateObserver();

  RegisteredObserverList observer_list(target.get());

  // No type of mutation is set.
  MutationObserverInit options;
  EXPECT_FALSE(observer_list.AddMutationObserver(observer, options));
  EXPECT_EQ(0, observer_list.registered_observers().size());

  // |attributes| is set as false, but attribute old data is set.
  options.set_attributes(false);
  options.set_attribute_old_value(true);
  EXPECT_FALSE(observer_list.AddMutationObserver(observer, options));
  EXPECT_EQ(0, observer_list.registered_observers().size());

  // |character_data| is set as false, but attribute old data is set.
  options = MutationObserverInit();
  options.set_character_data(false);
  options.set_character_data_old_value(true);
  EXPECT_FALSE(observer_list.AddMutationObserver(observer, options));
  EXPECT_EQ(0, observer_list.registered_observers().size());
}

TEST_F(MutationObserverTest, InvalidOptionsRaisesException) {
  scoped_refptr<dom::Element> target = CreateDiv();
  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit invalid_options;

  script::testing::MockExceptionState exception_state;
  EXPECT_CALL(exception_state, SetSimpleExceptionVA(script::kTypeError, _, _));
  observer->Observe(target, invalid_options, &exception_state);
}

TEST_F(MutationObserverTest, AddChildNodes) {
  scoped_refptr<Element> root = CreateDiv();
  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit options;
  options.set_subtree(true);
  options.set_child_list(true);
  observer->Observe(root, options);

  scoped_refptr<Element> child1 = document()->CreateElement("div");
  scoped_refptr<Element> child2 = document()->CreateElement("div");
  ASSERT_TRUE(child1);
  ASSERT_TRUE(child2);

  root->AppendChild(child1);
  child1->AppendChild(child2);

  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  ASSERT_EQ(2, records.size());
  EXPECT_EQ("childList", records.at(0)->type());
  EXPECT_EQ(root, records.at(0)->target());
  ASSERT_TRUE(records.at(0)->removed_nodes());
  ASSERT_EQ(0, records.at(0)->removed_nodes()->length());
  ASSERT_TRUE(records.at(0)->added_nodes());
  ASSERT_EQ(1, records.at(0)->added_nodes()->length());
  EXPECT_EQ(child1, records.at(0)->added_nodes()->Item(0));

  EXPECT_EQ("childList", records.at(1)->type());
  EXPECT_EQ(child1, records.at(1)->target());
  ASSERT_TRUE(records.at(1)->removed_nodes());
  ASSERT_EQ(0, records.at(1)->removed_nodes()->length());
  ASSERT_TRUE(records.at(1)->added_nodes());
  ASSERT_EQ(1, records.at(1)->added_nodes()->length());
  EXPECT_EQ(child2, records.at(1)->added_nodes()->Item(0));
}

TEST_F(MutationObserverTest, RemoveChildNode) {
  scoped_refptr<Element> root = CreateDiv();
  scoped_refptr<Element> child1 = document()->CreateElement("div");
  scoped_refptr<Element> child2 = document()->CreateElement("div");
  ASSERT_TRUE(child1);
  ASSERT_TRUE(child2);

  root->AppendChild(child1);
  child1->AppendChild(child2);

  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit options;
  options.set_subtree(true);
  options.set_child_list(true);
  observer->Observe(root, options);

  child1->RemoveChild(child2);

  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  ASSERT_EQ(1, records.size());
  EXPECT_EQ("childList", records.at(0)->type());
  EXPECT_EQ(child1, records.at(0)->target());
  ASSERT_TRUE(records.at(0)->removed_nodes());
  ASSERT_EQ(1, records.at(0)->removed_nodes()->length());
  EXPECT_EQ(child2, records.at(0)->removed_nodes()->Item(0));
}

TEST_F(MutationObserverTest, MutateCharacterData) {
  scoped_refptr<Element> root = CreateDiv();
  scoped_refptr<Text> text = document()->CreateTextNode("initial-data");
  ASSERT_TRUE(text);
  root->AppendChild(text);

  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit options;
  options.set_subtree(true);
  options.set_character_data(true);
  observer->Observe(root, options);

  text->set_data("new-data");

  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  ASSERT_EQ(1, records.size());
  EXPECT_EQ("characterData", records.at(0)->type());
  EXPECT_EQ(text, records.at(0)->target());
  EXPECT_FALSE(records.at(0)->old_value());
}

TEST_F(MutationObserverTest, MutateCharacterDataWithOldValue) {
  scoped_refptr<Element> root = CreateDiv();
  scoped_refptr<Text> text = document()->CreateTextNode("initial-data");
  ASSERT_TRUE(text);
  root->AppendChild(text);

  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit options;
  options.set_subtree(true);
  options.set_character_data_old_value(true);
  observer->Observe(root, options);

  text->set_data("new-data");

  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  ASSERT_EQ(1, records.size());
  EXPECT_EQ("characterData", records.at(0)->type());
  EXPECT_EQ(text, records.at(0)->target());
  ASSERT_TRUE(records.at(0)->old_value());
  EXPECT_STREQ("initial-data", records.at(0)->old_value()->c_str());
}

TEST_F(MutationObserverTest, MutateAttribute) {
  scoped_refptr<Element> root = CreateDiv();
  root->SetAttribute("banana", "purple");
  root->SetAttribute("apple", "green");

  scoped_refptr<MutationObserver> observer = CreateObserver();
  script::Sequence<std::string> filter;
  filter.push_back("banana");
  MutationObserverInit options;
  options.set_attributes(true);
  options.set_attribute_filter(filter);
  observer->Observe(root, options);

  root->SetAttribute("banana", "yellow");
  root->SetAttribute("apple", "brown");

  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  ASSERT_EQ(1, records.size());
  EXPECT_EQ("attributes", records.at(0)->type());
  EXPECT_EQ(root, records.at(0)->target());
  EXPECT_FALSE(records.at(0)->old_value());
  ASSERT_TRUE(records.at(0)->attribute_name());
  EXPECT_STREQ("banana", records.at(0)->attribute_name()->c_str());
}

TEST_F(MutationObserverTest, MutateAttributeWithOldValue) {
  scoped_refptr<Element> root = CreateDiv();
  root->SetAttribute("banana", "purple");

  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit options;
  options.set_attribute_old_value(true);
  observer->Observe(root, options);

  root->SetAttribute("banana", "yellow");

  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  ASSERT_EQ(1, records.size());
  EXPECT_EQ("attributes", records.at(0)->type());
  EXPECT_EQ(root, records.at(0)->target());
  ASSERT_TRUE(records.at(0)->old_value());
  ASSERT_TRUE(records.at(0)->attribute_name());
  EXPECT_STREQ("banana", records.at(0)->attribute_name()->c_str());
  EXPECT_STREQ("purple", records.at(0)->old_value()->c_str());
}

TEST_F(MutationObserverTest, Disconnect) {
  scoped_refptr<Element> root = CreateDiv();
  scoped_refptr<Text> text = document()->CreateTextNode("initial-data");
  ASSERT_TRUE(text);
  root->AppendChild(text);

  scoped_refptr<MutationObserver> observer = CreateObserver();
  MutationObserverInit options;
  options.set_subtree(true);
  options.set_character_data(true);
  observer->Observe(root, options);

  // This should queue up a mutation record.
  text->set_data("new-data");

  observer->Disconnect();
  MutationObserver::MutationRecordSequence records = observer->TakeRecords();
  // MutationObserver.disconnect() should clear any queued records.
  EXPECT_EQ(0, records.size());

  // This should not queue a mutation record.
  text->set_data("more-new-data");
  records = observer->TakeRecords();
  EXPECT_EQ(0, records.size());
}

}  // namespace dom
}  // namespace cobalt
