// Copyright 2015 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/dom/node.h"

#include "cobalt/dom/document.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/global_stats.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/testing/mock_event_listener.h"
#include "cobalt/script/testing/fake_script_value.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::AllOf;
using ::testing::Eq;
using ::testing::IgnoreResult;
using ::testing::InSequence;
using ::testing::InvokeWithoutArgs;
using ::testing::Pointee;
using ::testing::Property;
using ::testing::_;

namespace cobalt {
namespace dom {

using ::cobalt::script::testing::FakeScriptValue;
using testing::MockEventListener;

//////////////////////////////////////////////////////////////////////////
// NodeDispatchEventTest
//////////////////////////////////////////////////////////////////////////

class NodeDispatchEventTest : public ::testing::Test {
 protected:
  NodeDispatchEventTest();
  ~NodeDispatchEventTest() override;

  HTMLElementContext html_element_context_;
  scoped_refptr<Document> document_;

  scoped_refptr<Node> grand_parent_;
  scoped_refptr<Node> parent_;
  scoped_refptr<Node> child_;
  scoped_ptr<MockEventListener> event_listener_capture_;
  scoped_ptr<MockEventListener> event_listener_bubbling_;
};

NodeDispatchEventTest::NodeDispatchEventTest() {
  EXPECT_TRUE(GlobalStats::GetInstance()->CheckNoLeaks());

  document_ = new Document(&html_element_context_);

  grand_parent_ = new Element(document_);
  parent_ = grand_parent_->AppendChild(new Element(document_));
  child_ = parent_->AppendChild(new Element(document_));
  event_listener_capture_ = MockEventListener::Create();
  event_listener_bubbling_ = MockEventListener::Create();

  grand_parent_->AddEventListener(
      "fired",
      FakeScriptValue<EventListener>(event_listener_bubbling_.get()), false);
  grand_parent_->AddEventListener(
      "fired",
      FakeScriptValue<EventListener>(event_listener_capture_.get()), true);
  parent_->AddEventListener(
      "fired",
      FakeScriptValue<EventListener>(event_listener_bubbling_.get()), false);
  parent_->AddEventListener(
      "fired",
      FakeScriptValue<EventListener>(event_listener_capture_.get()), true);
  child_->AddEventListener(
      "fired",
      FakeScriptValue<EventListener>(event_listener_bubbling_.get()), false);
  child_->AddEventListener(
      "fired",
      FakeScriptValue<EventListener>(event_listener_capture_.get()), true);
}

NodeDispatchEventTest::~NodeDispatchEventTest() {
  grand_parent_ = NULL;
  parent_ = NULL;
  child_ = NULL;
  event_listener_capture_.reset();
  event_listener_bubbling_.reset();

  document_ = NULL;

  EXPECT_TRUE(GlobalStats::GetInstance()->CheckNoLeaks());
}

//////////////////////////////////////////////////////////////////////////
// Test cases
//////////////////////////////////////////////////////////////////////////

TEST_F(NodeDispatchEventTest, NonBubblingEventPropagation) {
  scoped_refptr<Event> event = new Event(
      base::Token("fired"), Event::kNotBubbles, Event::kNotCancelable);

  InSequence in_sequence;
  event_listener_capture_->ExpectHandleEventCall(event, child_, grand_parent_,
                                                 Event::kCapturingPhase);
  event_listener_capture_->ExpectHandleEventCall(event, child_, parent_,
                                                 Event::kCapturingPhase);
  // The event listeners called at target are always in the order of append.
  event_listener_bubbling_->ExpectHandleEventCall(event, child_, child_,
                                                  Event::kAtTarget);
  event_listener_capture_->ExpectHandleEventCall(event, child_, child_,
                                                 Event::kAtTarget);
  EXPECT_TRUE(child_->DispatchEvent(event));
}

TEST_F(NodeDispatchEventTest, BubblingEventPropagation) {
  scoped_refptr<Event> event =
      new Event(base::Token("fired"), Event::kBubbles, Event::kNotCancelable);

  InSequence in_sequence;
  event_listener_capture_->ExpectHandleEventCall(event, child_, grand_parent_,
                                                 Event::kCapturingPhase);
  event_listener_capture_->ExpectHandleEventCall(event, child_, parent_,
                                                 Event::kCapturingPhase);
  // The event listeners called at target are always in the order of append.
  event_listener_bubbling_->ExpectHandleEventCall(event, child_, child_,
                                                  Event::kAtTarget);
  event_listener_capture_->ExpectHandleEventCall(event, child_, child_,
                                                 Event::kAtTarget);
  event_listener_bubbling_->ExpectHandleEventCall(event, child_, parent_,
                                                  Event::kBubblingPhase);
  event_listener_bubbling_->ExpectHandleEventCall(event, child_, grand_parent_,
                                                  Event::kBubblingPhase);
  EXPECT_TRUE(child_->DispatchEvent(event));
}

TEST_F(NodeDispatchEventTest, StopPropagationAtCapturePhase) {
  scoped_refptr<Event> event =
      new Event(base::Token("fired"), Event::kBubbles, Event::kNotCancelable);

  InSequence in_sequence;
  event_listener_capture_->ExpectHandleEventCall(event, child_, grand_parent_,
                                                 Event::kCapturingPhase);
  event_listener_capture_->ExpectHandleEventCall(
      event, child_, parent_, Event::kCapturingPhase,
      &MockEventListener::StopPropagation);
  EXPECT_TRUE(child_->DispatchEvent(event));
}

TEST_F(NodeDispatchEventTest, StopPropagationAtAtTargetPhase) {
  scoped_refptr<Event> event =
      new Event(base::Token("fired"), Event::kBubbles, Event::kNotCancelable);

  InSequence in_sequence;
  event_listener_capture_->ExpectHandleEventCall(event, child_, grand_parent_,
                                                 Event::kCapturingPhase);
  event_listener_capture_->ExpectHandleEventCall(event, child_, parent_,
                                                 Event::kCapturingPhase);
  event_listener_bubbling_->ExpectHandleEventCall(
      event, child_, child_, Event::kAtTarget,
      &MockEventListener::StopPropagation);
  event_listener_capture_->ExpectHandleEventCall(event, child_, child_,
                                                 Event::kAtTarget);
  EXPECT_TRUE(child_->DispatchEvent(event));
}

TEST_F(NodeDispatchEventTest, StopPropagationAtBubblingPhase) {
  scoped_refptr<Event> event =
      new Event(base::Token("fired"), Event::kBubbles, Event::kNotCancelable);

  InSequence in_sequence;
  event_listener_capture_->ExpectHandleEventCall(event, child_, grand_parent_,
                                                 Event::kCapturingPhase);
  event_listener_capture_->ExpectHandleEventCall(event, child_, parent_,
                                                 Event::kCapturingPhase);
  // The event listeners called at target are always in the order of append.
  event_listener_bubbling_->ExpectHandleEventCall(event, child_, child_,
                                                  Event::kAtTarget);
  event_listener_capture_->ExpectHandleEventCall(event, child_, child_,
                                                 Event::kAtTarget);
  event_listener_bubbling_->ExpectHandleEventCall(
      event, child_, parent_, Event::kBubblingPhase,
      &MockEventListener::StopPropagation);
  EXPECT_TRUE(child_->DispatchEvent(event));
}

TEST_F(NodeDispatchEventTest, StopImmediatePropagation) {
  scoped_refptr<Event> event =
      new Event(base::Token("fired"), Event::kBubbles, Event::kNotCancelable);

  InSequence in_sequence;
  event_listener_capture_->ExpectHandleEventCall(event, child_, grand_parent_,
                                                 Event::kCapturingPhase);
  event_listener_capture_->ExpectHandleEventCall(event, child_, parent_,
                                                 Event::kCapturingPhase);
  event_listener_bubbling_->ExpectHandleEventCall(
      event, child_, child_, Event::kAtTarget,
      &MockEventListener::StopImmediatePropagation);
  EXPECT_TRUE(child_->DispatchEvent(event));
}

TEST_F(NodeDispatchEventTest, PreventDefaultOnNonCancelableEvent) {
  scoped_refptr<Event> event =
      new Event(base::Token("fired"), Event::kBubbles, Event::kNotCancelable);

  InSequence in_sequence;
  event_listener_capture_->ExpectHandleEventCall(
      event, child_, grand_parent_, Event::kCapturingPhase,
      &MockEventListener::PreventDefault);
  event_listener_capture_->ExpectHandleEventCall(
      event, child_, parent_, Event::kCapturingPhase,
      &MockEventListener::StopPropagation);
  EXPECT_TRUE(child_->DispatchEvent(event));
}

TEST_F(NodeDispatchEventTest, PreventDefaultOnCancelableEvent) {
  scoped_refptr<Event> event =
      new Event(base::Token("fired"), Event::kBubbles, Event::kCancelable);

  InSequence in_sequence;
  event_listener_capture_->ExpectHandleEventCall(
      event, child_, grand_parent_, Event::kCapturingPhase,
      &MockEventListener::PreventDefault);
  event_listener_capture_->ExpectHandleEventCall(
      event, child_, parent_, Event::kCapturingPhase,
      &MockEventListener::StopPropagation);
  EXPECT_FALSE(child_->DispatchEvent(event));
}

}  // namespace dom
}  // namespace cobalt
