// 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/event_target.h"

#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/dom/dom_exception.h"
#include "cobalt/dom/testing/mock_event_listener.h"
#include "cobalt/script/testing/mock_exception_state.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace dom {
namespace {

using ::testing::AllOf;
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::Pointee;
using ::testing::Property;
using ::testing::SaveArg;
using ::testing::StrictMock;
using ::testing::_;
using script::testing::MockExceptionState;
using testing::FakeScriptValue;
using testing::MockEventListener;

base::optional<bool> DispatchEventOnCurrentTarget(
    const scoped_refptr<script::Wrappable>, const scoped_refptr<Event>& event,
    bool*) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<script::ScriptException> exception;

  EXPECT_TRUE(event->IsBeingDispatched());

  EXPECT_CALL(exception_state, SetException(_))
      .WillOnce(SaveArg<0>(&exception));
  event->current_target()->DispatchEvent(event, &exception_state);

  EXPECT_TRUE(exception);
  if (!exception) {
    EXPECT_EQ(
        DOMException::kInvalidStateErr,
        base::polymorphic_downcast<DOMException*>(exception.get())->code());
  }
  return base::nullopt;
}

TEST(EventTargetTest, SingleEventListenerFired) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listener = MockEventListener::Create();

  event_listener->ExpectHandleEventCall(event, event_target);
  event_target->AddEventListener("fired",
                                 FakeScriptValue(event_listener.get()), false);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

TEST(EventTargetTest, SingleEventListenerNotFired) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listener = MockEventListener::Create();

  event_listener->ExpectNoHandleEventCall();
  event_target->AddEventListener("notfired",
                                 FakeScriptValue(event_listener.get()), false);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

// Test if multiple event listeners of different event types can be added and
// fired properly.
TEST(EventTargetTest, MultipleEventListeners) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listenerfired_1 =
      MockEventListener::Create();
  scoped_ptr<MockEventListener> event_listenerfired_2 =
      MockEventListener::Create();
  scoped_ptr<MockEventListener> event_listenernot_fired =
      MockEventListener::Create();

  InSequence in_sequence;
  event_listenerfired_1->ExpectHandleEventCall(event, event_target);
  event_listenerfired_2->ExpectHandleEventCall(event, event_target);
  event_listenernot_fired->ExpectNoHandleEventCall();

  event_target->AddEventListener(
      "fired", FakeScriptValue(event_listenerfired_1.get()), false);
  event_target->AddEventListener(
      "notfired", FakeScriptValue(event_listenernot_fired.get()), false);
  event_target->AddEventListener(
      "fired", FakeScriptValue(event_listenerfired_2.get()), true);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

// Test if event listener can be added and later removed.
TEST(EventTargetTest, AddRemoveEventListener) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listener = MockEventListener::Create();

  event_listener->ExpectHandleEventCall(event, event_target);
  event_target->AddEventListener("fired",
                                 FakeScriptValue(event_listener.get()), false);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));

  event_listener->ExpectNoHandleEventCall();
  event_target->RemoveEventListener(
      "fired", FakeScriptValue(event_listener.get()), false);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));

  event_listener->ExpectHandleEventCall(event, event_target);
  event_target->AddEventListener("fired",
                                 FakeScriptValue(event_listener.get()), false);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

// Test if attribute event listener works.
TEST(EventTargetTest, AttributeListener) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> non_attribute_event_listener =
      MockEventListener::Create();
  scoped_ptr<MockEventListener> attribute_event_listener1 =
      MockEventListener::Create();
  scoped_ptr<MockEventListener> attribute_event_listener2 =
      MockEventListener::Create();

  event_target->AddEventListener(
      "fired", FakeScriptValue(non_attribute_event_listener.get()), false);

  non_attribute_event_listener->ExpectHandleEventCall(event, event_target);
  attribute_event_listener1->ExpectHandleEventCall(event, event_target);
  event_target->SetAttributeEventListener(
      base::Token("fired"), FakeScriptValue(attribute_event_listener1.get()));
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));

  non_attribute_event_listener->ExpectHandleEventCall(event, event_target);
  attribute_event_listener1->ExpectNoHandleEventCall();
  attribute_event_listener2->ExpectHandleEventCall(event, event_target);
  event_target->SetAttributeEventListener(
      base::Token("fired"), FakeScriptValue(attribute_event_listener2.get()));
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));

  non_attribute_event_listener->ExpectHandleEventCall(event, event_target);
  attribute_event_listener1->ExpectNoHandleEventCall();
  attribute_event_listener2->ExpectNoHandleEventCall();
  event_target->SetAttributeEventListener(base::Token("fired"),
                                          FakeScriptValue(NULL));
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

// Test if one event listener can be used by multiple events.
TEST(EventTargetTest, EventListenerReuse) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event_1 = new Event(base::Token("fired_1"));
  scoped_refptr<Event> event_2 = new Event(base::Token("fired_2"));
  scoped_ptr<MockEventListener> event_listener = MockEventListener::Create();

  event_listener->ExpectHandleEventCall(event_1, event_target);
  event_listener->ExpectHandleEventCall(event_2, event_target);
  event_target->AddEventListener("fired_1",
                                 FakeScriptValue(event_listener.get()), false);
  event_target->AddEventListener("fired_2",
                                 FakeScriptValue(event_listener.get()), false);
  EXPECT_TRUE(event_target->DispatchEvent(event_1, &exception_state));
  EXPECT_TRUE(event_target->DispatchEvent(event_2, &exception_state));

  event_listener->ExpectHandleEventCall(event_1, event_target);
  event_target->RemoveEventListener(
      "fired_2", FakeScriptValue(event_listener.get()), false);
  EXPECT_TRUE(event_target->DispatchEvent(event_1, &exception_state));
  EXPECT_TRUE(event_target->DispatchEvent(event_2, &exception_state));

  event_listener->ExpectHandleEventCall(event_1, event_target);
  // The capture flag is not the same so the event will not be removed.
  event_target->RemoveEventListener(
      "fired_1", FakeScriptValue(event_listener.get()), true);
  EXPECT_TRUE(event_target->DispatchEvent(event_1, &exception_state));
  EXPECT_TRUE(event_target->DispatchEvent(event_2, &exception_state));

  event_listener->ExpectNoHandleEventCall();
  event_target->RemoveEventListener(
      "fired_1", FakeScriptValue(event_listener.get()), false);
  EXPECT_TRUE(event_target->DispatchEvent(event_1, &exception_state));
  EXPECT_TRUE(event_target->DispatchEvent(event_2, &exception_state));
}

TEST(EventTargetTest, StopPropagation) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listenerfired_1 =
      MockEventListener::Create();
  scoped_ptr<MockEventListener> event_listenerfired_2 =
      MockEventListener::Create();

  InSequence in_sequence;
  event_listenerfired_1->ExpectHandleEventCall(
      event, event_target, &MockEventListener::StopPropagation);
  event_listenerfired_2->ExpectHandleEventCall(event, event_target);

  event_target->AddEventListener(
      "fired", FakeScriptValue(event_listenerfired_1.get()), false);
  event_target->AddEventListener(
      "fired", FakeScriptValue(event_listenerfired_2.get()), true);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

TEST(EventTargetTest, StopImmediatePropagation) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listenerfired_1 =
      MockEventListener::Create();
  scoped_ptr<MockEventListener> event_listenerfired_2 =
      MockEventListener::Create();

  event_listenerfired_1->ExpectHandleEventCall(
      event, event_target, &MockEventListener::StopImmediatePropagation);
  event_listenerfired_2->ExpectNoHandleEventCall();

  event_target->AddEventListener(
      "fired", FakeScriptValue(event_listenerfired_1.get()), false);
  event_target->AddEventListener(
      "fired", FakeScriptValue(event_listenerfired_2.get()), true);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

TEST(EventTargetTest, PreventDefault) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<Event> event;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_ptr<MockEventListener> event_listenerfired =
      MockEventListener::Create();

  event_target->AddEventListener(
      "fired", FakeScriptValue(event_listenerfired.get()), false);
  event = new Event(base::Token("fired"), Event::kNotBubbles,
                    Event::kNotCancelable);
  event_listenerfired->ExpectHandleEventCall(
      event, event_target, &MockEventListener::PreventDefault);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));

  event =
      new Event(base::Token("fired"), Event::kNotBubbles, Event::kCancelable);
  event_listenerfired->ExpectHandleEventCall(
      event, event_target, &MockEventListener::PreventDefault);
  EXPECT_FALSE(event_target->DispatchEvent(event, &exception_state));
}

TEST(EventTargetTest, RaiseException) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<script::ScriptException> exception;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event;
  scoped_ptr<MockEventListener> event_listener = MockEventListener::Create();

  EXPECT_CALL(exception_state, SetException(_))
      .WillOnce(SaveArg<0>(&exception));
  // Dispatch a NULL event.
  event_target->DispatchEvent(NULL, &exception_state);
  ASSERT_TRUE(exception);
  EXPECT_EQ(DOMException::kInvalidStateErr,
            base::polymorphic_downcast<DOMException*>(exception.get())->code());
  exception = NULL;

  EXPECT_CALL(exception_state, SetException(_))
      .WillOnce(SaveArg<0>(&exception));
  // Dispatch an uninitialized event.
  event_target->DispatchEvent(new Event(Event::Uninitialized),
                              &exception_state);
  ASSERT_TRUE(exception);
  EXPECT_EQ(DOMException::kInvalidStateErr,
            base::polymorphic_downcast<DOMException*>(exception.get())->code());
  exception = NULL;

  event_target->AddEventListener("fired",
                                 FakeScriptValue(event_listener.get()), false);
  event = new Event(base::Token("fired"), Event::kNotBubbles,
                    Event::kNotCancelable);
  // Dispatch event again when it is being dispatched.
  EXPECT_CALL(*event_listener, HandleEvent(_, _, _))
      .WillOnce(Invoke(DispatchEventOnCurrentTarget));
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

TEST(EventTargetTest, AddSameListenerMultipleTimes) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listener = MockEventListener::Create();
  FakeScriptValue script_object(event_listener.get());

  InSequence in_sequence;
  event_listener->ExpectHandleEventCall(event, event_target);

  // The same listener should only get added once.
  event_target->AddEventListener("fired", script_object, false);
  event_target->AddEventListener("fired", script_object, false);
  event_target->AddEventListener("fired", script_object, false);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

TEST(EventTargetTest, AddSameAttributeListenerMultipleTimes) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listener = MockEventListener::Create();
  FakeScriptValue script_object(event_listener.get());

  InSequence in_sequence;
  event_listener->ExpectHandleEventCall(event, event_target);

  // The same listener should only get added once.
  event_target->SetAttributeEventListener(base::Token("fired"), script_object);
  event_target->SetAttributeEventListener(base::Token("fired"), script_object);
  event_target->SetAttributeEventListener(base::Token("fired"), script_object);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

TEST(EventTargetTest, SameEventListenerAsAttribute) {
  StrictMock<MockExceptionState> exception_state;
  scoped_refptr<EventTarget> event_target = new EventTarget;
  scoped_refptr<Event> event = new Event(base::Token("fired"));
  scoped_ptr<MockEventListener> event_listener = MockEventListener::Create();
  FakeScriptValue script_object(event_listener.get());

  InSequence in_sequence;
  event_listener->ExpectHandleEventCall(event, event_target);
  event_listener->ExpectHandleEventCall(event, event_target);

  // The same script object can be registered as both an attribute and
  // non-attribute listener. Both should be fired.
  event_target->AddEventListener("fired", script_object, false);
  event_target->SetAttributeEventListener(base::Token("fired"), script_object);
  EXPECT_TRUE(event_target->DispatchEvent(event, &exception_state));
}

}  // namespace
}  // namespace dom
}  // namespace cobalt
