/*
 * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "bindings/core/v8/V8AbstractEventListener.h"

#include "bindings/core/v8/V8Binding.h"
#include "bindings/core/v8/V8Event.h"
#include "bindings/core/v8/V8EventListenerHelper.h"
#include "bindings/core/v8/V8EventTarget.h"
#include "bindings/core/v8/V8HiddenValue.h"
#include "core/events/BeforeUnloadEvent.h"
#include "core/events/Event.h"
#include "core/inspector/InstanceCounters.h"
#include "core/workers/WorkerGlobalScope.h"

namespace blink {

V8AbstractEventListener::V8AbstractEventListener(bool isAttribute,
                                                 DOMWrapperWorld& world,
                                                 v8::Isolate* isolate)
    : EventListener(JSEventListenerType),
      m_isAttribute(isAttribute),
      m_world(world),
      m_isolate(isolate),
      m_workerGlobalScope(nullptr) {
  if (isMainThread())
    InstanceCounters::incrementCounter(
        InstanceCounters::JSEventListenerCounter);
  else
    m_workerGlobalScope = toWorkerGlobalScope(currentExecutionContext(isolate));
}

V8AbstractEventListener::~V8AbstractEventListener() {
  ASSERT(m_listener.isEmpty());
  if (isMainThread())
    InstanceCounters::decrementCounter(
        InstanceCounters::JSEventListenerCounter);
}

void V8AbstractEventListener::handleEvent(ExecutionContext* executionContext,
                                          Event* event) {
  if (!executionContext)
    return;
  // Don't reenter V8 if execution was terminated in this instance of V8.
  if (executionContext->isJSExecutionForbidden())
    return;

  // A ScriptState used by the event listener needs to be calculated based on
  // the ExecutionContext that fired the the event listener and the world
  // that installed the event listener.
  ASSERT(event);
  v8::HandleScope handleScope(toIsolate(executionContext));
  v8::Local<v8::Context> v8Context = toV8Context(executionContext, world());
  if (v8Context.IsEmpty())
    return;
  ScriptState* scriptState = ScriptState::from(v8Context);
  if (!scriptState->contextIsValid())
    return;
  handleEvent(scriptState, event);
}

void V8AbstractEventListener::handleEvent(ScriptState* scriptState,
                                          Event* event) {
  ScriptState::Scope scope(scriptState);

  // Get the V8 wrapper for the event object.
  v8::Local<v8::Value> jsEvent =
      toV8(event, scriptState->context()->Global(), isolate());
  if (jsEvent.IsEmpty())
    return;
  invokeEventHandler(scriptState, event,
                     v8::Local<v8::Value>::New(isolate(), jsEvent));
}

void V8AbstractEventListener::setListenerObject(
    v8::Local<v8::Object> listener) {
  ASSERT(m_listener.isEmpty());
  // Balanced in wrapperCleared xor clearListenerObject.
  if (m_workerGlobalScope) {
    m_workerGlobalScope->registerEventListener(this);
  } else {
    m_keepAlive = this;
  }
  m_listener.set(isolate(), listener);
  m_listener.setWeak(this, &wrapperCleared);
}

void V8AbstractEventListener::invokeEventHandler(ScriptState* scriptState,
                                                 Event* event,
                                                 v8::Local<v8::Value> jsEvent) {
  if (!event->canBeDispatchedInWorld(world()))
    return;

  v8::Local<v8::Value> returnValue;
  {
    // Catch exceptions thrown in the event handler so they do not propagate to javascript code that caused the event to fire.
    v8::TryCatch tryCatch(isolate());
    tryCatch.SetVerbose(true);

    // Save the old 'event' property so we can restore it later.
    v8::Local<v8::Value> savedEvent = V8HiddenValue::getHiddenValue(
        scriptState, scriptState->context()->Global(),
        V8HiddenValue::event(isolate()));
    tryCatch.Reset();

    // Make the event available in the global object, so LocalDOMWindow can expose it.
    V8HiddenValue::setHiddenValue(scriptState, scriptState->context()->Global(),
                                  V8HiddenValue::event(isolate()), jsEvent);
    tryCatch.Reset();

    returnValue = callListenerFunction(scriptState, jsEvent, event);
    if (tryCatch.HasCaught())
      event->target()->uncaughtExceptionInEventHandler();

    if (!tryCatch.CanContinue()) {  // Result of TerminateExecution().
      if (scriptState->getExecutionContext()->isWorkerGlobalScope())
        toWorkerGlobalScope(scriptState->getExecutionContext())
            ->scriptController()
            ->forbidExecution();
      return;
    }
    tryCatch.Reset();

    // Restore the old event. This must be done for all exit paths through this method.
    if (savedEvent.IsEmpty())
      V8HiddenValue::setHiddenValue(
          scriptState, scriptState->context()->Global(),
          V8HiddenValue::event(isolate()), v8::Undefined(isolate()));
    else
      V8HiddenValue::setHiddenValue(
          scriptState, scriptState->context()->Global(),
          V8HiddenValue::event(isolate()), savedEvent);
    tryCatch.Reset();
  }

  if (returnValue.IsEmpty())
    return;

  if (m_isAttribute && !returnValue->IsNull() && !returnValue->IsUndefined() &&
      event->isBeforeUnloadEvent()) {
    TOSTRING_VOID(V8StringResource<>, stringReturnValue, returnValue);
    toBeforeUnloadEvent(event)->setReturnValue(stringReturnValue);
  }

  if (m_isAttribute && shouldPreventDefault(returnValue))
    event->preventDefault();
}

bool V8AbstractEventListener::shouldPreventDefault(
    v8::Local<v8::Value> returnValue) {
  // Prevent default action if the return value is false in accord with the spec
  // http://www.w3.org/TR/html5/webappapis.html#event-handler-attributes
  return returnValue->IsBoolean() && !returnValue.As<v8::Boolean>()->Value();
}

v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(
    ScriptState* scriptState,
    Event* event) {
  v8::Local<v8::Object> listener = m_listener.newLocal(isolate());
  if (!m_listener.isEmpty() && !listener->IsFunction())
    return listener;

  EventTarget* target = event->currentTarget();
  v8::Local<v8::Value> value =
      toV8(target, scriptState->context()->Global(), isolate());
  if (value.IsEmpty())
    return v8::Local<v8::Object>();
  return v8::Local<v8::Object>::New(isolate(),
                                    v8::Local<v8::Object>::Cast(value));
}

bool V8AbstractEventListener::belongsToTheCurrentWorld() const {
  return ScriptState::hasCurrentScriptState(isolate()) &&
         &world() == &DOMWrapperWorld::current(isolate());
}

void V8AbstractEventListener::clearListenerObject() {
  if (!hasExistingListenerObject())
    return;
  m_listener.clear();
  if (m_workerGlobalScope) {
    m_workerGlobalScope->deregisterEventListener(this);
  } else {
    m_keepAlive.clear();
  }
}

void V8AbstractEventListener::wrapperCleared(
    const v8::WeakCallbackInfo<V8AbstractEventListener>& data) {
  data.GetParameter()->clearListenerObject();
}

DEFINE_TRACE(V8AbstractEventListener) {
  visitor->trace(m_workerGlobalScope);
  EventListener::trace(visitor);
}

DEFINE_TRACE_WRAPPERS(V8AbstractEventListener) {
  visitor->traceWrappers(&m_listener);
}

}  // namespace blink
