/*
 * Copyright 2015 Google Inc. 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 "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 testing::FakeScriptObject;
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()
    : html_element_context_(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                            NULL, NULL, NULL, NULL, "") {
  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", FakeScriptObject(event_listener_bubbling_.get()), false);
  grand_parent_->AddEventListener(
      "fired", FakeScriptObject(event_listener_capture_.get()), true);
  parent_->AddEventListener(
      "fired", FakeScriptObject(event_listener_bubbling_.get()), false);
  parent_->AddEventListener(
      "fired", FakeScriptObject(event_listener_capture_.get()), true);
  child_->AddEventListener(
      "fired", FakeScriptObject(event_listener_bubbling_.get()), false);
  child_->AddEventListener(
      "fired", FakeScriptObject(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
