// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "web/SuspendableScriptExecutor.h"

#include "bindings/core/v8/ScriptController.h"
#include "bindings/core/v8/ScriptSourceCode.h"
#include "core/dom/Document.h"
#include "core/frame/LocalFrame.h"
#include "platform/UserGestureIndicator.h"
#include "public/platform/WebVector.h"
#include "public/web/WebScriptExecutionCallback.h"

namespace blink {

void SuspendableScriptExecutor::createAndRun(LocalFrame* frame, int worldID, const WillBeHeapVector<ScriptSourceCode>& sources, int extensionGroup, bool userGesture, WebScriptExecutionCallback* callback)
{
    SuspendableScriptExecutor* executor = new SuspendableScriptExecutor(frame, worldID, sources, extensionGroup, userGesture, callback);
    executor->run();
}

void SuspendableScriptExecutor::contextDestroyed()
{
    SuspendableTimer::contextDestroyed();
    m_callback->completed(Vector<v8::Local<v8::Value>>());
    dispose();
}

SuspendableScriptExecutor::SuspendableScriptExecutor(LocalFrame* frame, int worldID, const WillBeHeapVector<ScriptSourceCode>& sources, int extensionGroup, bool userGesture, WebScriptExecutionCallback* callback)
    : SuspendableTimer(frame->document())
    , m_frame(frame)
    , m_sources(sources)
    , m_callback(callback)
    , m_keepAlive(this)
    , m_worldID(worldID)
    , m_extensionGroup(extensionGroup)
    , m_userGesture(userGesture)
{
}

SuspendableScriptExecutor::~SuspendableScriptExecutor()
{
}

void SuspendableScriptExecutor::fired()
{
    executeAndDestroySelf();
}

void SuspendableScriptExecutor::run()
{
    ExecutionContext* context = executionContext();
    ASSERT(context);
    if (!context->activeDOMObjectsAreSuspended()) {
        suspendIfNeeded();
        executeAndDestroySelf();
        return;
    }
    startOneShot(0, BLINK_FROM_HERE);
    suspendIfNeeded();
}

void SuspendableScriptExecutor::executeAndDestroySelf()
{
    // after calling the destructor of object - object will be unsubscribed from
    // resumed and contextDestroyed LifecycleObserver methods
    OwnPtr<UserGestureIndicator> indicator;
    if (m_userGesture)
        indicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessingNewUserGesture));

    v8::HandleScope scope(v8::Isolate::GetCurrent());
    Vector<v8::Local<v8::Value>> results;
    if (m_worldID) {
        m_frame->script().executeScriptInIsolatedWorld(m_worldID, m_sources, m_extensionGroup, &results);
    } else {
        v8::Local<v8::Value> scriptValue = m_frame->script().executeScriptInMainWorldAndReturnValue(m_sources.first());
        results.append(scriptValue);
    }

    // The script may have removed the frame, in which case contextDestroyed()
    // will have handled the disposal/callback.
    if (!m_frame->client())
        return;

    m_callback->completed(results);
    dispose();
}

void SuspendableScriptExecutor::dispose()
{
    // Remove object as a ContextLifecycleObserver.
    ActiveDOMObject::clearContext();
    m_keepAlive.clear();
    stop();
}

DEFINE_TRACE(SuspendableScriptExecutor)
{
    visitor->trace(m_frame);
    visitor->trace(m_sources);
    SuspendableTimer::trace(visitor);
}

} // namespace blink
