/*
 * Copyright (C) 2010 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 "config.h"
#include "modules/webdatabase/DatabaseObserver.h"

#include "WebCommonWorkerClient.h"
#include "WebDatabase.h"
#include "WebDatabaseObserver.h"
#include "WebFrameClient.h"
#include "WebFrameImpl.h"
#include "WebPermissionClient.h"
#include "WebSecurityOrigin.h"
#include "WebViewImpl.h"
#include "WebWorkerBase.h"
#include "WorkerAllowMainThreadBridgeBase.h"
#include "bindings/v8/WorkerScriptController.h"
#include "core/dom/CrossThreadTask.h"
#include "core/dom/Document.h"
#include "core/dom/ScriptExecutionContext.h"
#include "core/platform/CrossThreadCopier.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerLoaderProxy.h"
#include "core/workers/WorkerThread.h"
#include "modules/webdatabase/DatabaseBackendBase.h"
#include "modules/webdatabase/DatabaseBackendContext.h"

using namespace WebKit;

namespace {

static const char allowDatabaseMode[] = "allowDatabaseMode";

// This class is used to route the result of the WebWorkerBase::allowDatabase
// call back to the worker context.
class AllowDatabaseMainThreadBridge : public WorkerAllowMainThreadBridgeBase {
public:
    static PassRefPtr<AllowDatabaseMainThreadBridge> create(WebCore::WorkerGlobalScope* workerGlobalScope, WebWorkerBase* webWorkerBase, const String& mode, WebFrame* frame, const String& name, const String& displayName, unsigned long estimatedSize)
    {
        return adoptRef(new AllowDatabaseMainThreadBridge(workerGlobalScope, webWorkerBase, mode, frame, name, displayName, estimatedSize));
    }

private:
    class AllowDatabaseParams : public AllowParams
    {
    public:
        AllowDatabaseParams(const String& mode, WebFrame* frame, const String& name, const String& displayName, unsigned long estimatedSize)
            : AllowParams(mode)
            , m_frame(WebCore::AllowCrossThreadAccess(frame))
            , m_name(name.isolatedCopy())
            , m_displayName(displayName.isolatedCopy())
            , m_estimatedSize(estimatedSize)
        {
        }
        WebCore::AllowCrossThreadAccessWrapper<WebFrame> m_frame;
        String m_name;
        String m_displayName;
        unsigned long m_estimatedSize;
    };

    AllowDatabaseMainThreadBridge(WebCore::WorkerGlobalScope* workerGlobalScope, WebWorkerBase* webWorkerBase, const String& mode, WebFrame* frame, const String& name, const String& displayName, unsigned long estimatedSize)
        : WorkerAllowMainThreadBridgeBase(workerGlobalScope, webWorkerBase)
    {
        postTaskToMainThread(
            adoptPtr(new AllowDatabaseParams(mode, frame, name, displayName, estimatedSize)));
    }

    virtual bool allowOnMainThread(WebCommonWorkerClient* commonClient, AllowParams* params)
    {
        ASSERT(isMainThread());
        AllowDatabaseParams* allowDBParams = static_cast<AllowDatabaseParams*>(params);
        return commonClient->allowDatabase(
            allowDBParams->m_frame.value(), allowDBParams->m_name, allowDBParams->m_displayName, allowDBParams->m_estimatedSize);
    }
};

bool allowDatabaseForWorker(WebFrame* frame, const WebString& name, const WebString& displayName, unsigned long estimatedSize)
{
    WebCore::WorkerScriptController* controller = WebCore::WorkerScriptController::controllerForContext();
    WebCore::WorkerGlobalScope* workerGlobalScope = controller->workerGlobalScope();
    WebCore::WorkerThread* workerThread = workerGlobalScope->thread();
    WebCore::WorkerRunLoop& runLoop = workerThread->runLoop();
    WebCore::WorkerLoaderProxy* workerLoaderProxy = &workerThread->workerLoaderProxy();

    // Create a unique mode just for this synchronous call.
    String mode = allowDatabaseMode;
    mode.append(String::number(runLoop.createUniqueId()));

    RefPtr<AllowDatabaseMainThreadBridge> bridge = AllowDatabaseMainThreadBridge::create(workerGlobalScope, workerLoaderProxy->toWebWorkerBase(), mode, frame, name, displayName, estimatedSize);

    // Either the bridge returns, or the queue gets terminated.
    if (runLoop.runInMode(workerGlobalScope, mode) == MessageQueueTerminated) {
        bridge->cancel();
        return false;
    }

    return bridge->result();
}

}

namespace WebCore {

bool DatabaseObserver::canEstablishDatabase(ScriptExecutionContext* scriptExecutionContext, const String& name, const String& displayName, unsigned long estimatedSize)
{
    ASSERT(scriptExecutionContext->isContextThread());
    ASSERT(scriptExecutionContext->isDocument() || scriptExecutionContext->isWorkerGlobalScope());
    if (scriptExecutionContext->isDocument()) {
        Document* document = toDocument(scriptExecutionContext);
        WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
        if (!webFrame)
            return false;
        WebViewImpl* webView = webFrame->viewImpl();
        if (!webView)
            return false;
        if (webView->permissionClient())
            return webView->permissionClient()->allowDatabase(webFrame, name, displayName, estimatedSize);
    } else {
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(scriptExecutionContext);
        WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerGlobalScope->thread()->workerLoaderProxy().toWebWorkerBase());
        WebView* view = webWorker->view();
        if (!view)
            return false;
        return allowDatabaseForWorker(view->mainFrame(), name, displayName, estimatedSize);
    }

    return true;
}

void DatabaseObserver::databaseOpened(DatabaseBackendBase* database)
{
    ASSERT(database->databaseContext()->scriptExecutionContext()->isContextThread());
    WebDatabase::observer()->databaseOpened(WebDatabase(database));
}

void DatabaseObserver::databaseModified(DatabaseBackendBase* database)
{
    ASSERT(database->databaseContext()->scriptExecutionContext()->isContextThread());
    WebDatabase::observer()->databaseModified(WebDatabase(database));
}

void DatabaseObserver::databaseClosed(DatabaseBackendBase* database)
{
    ASSERT(database->databaseContext()->scriptExecutionContext()->isContextThread());
    WebDatabase::observer()->databaseClosed(WebDatabase(database));
}

void DatabaseObserver::reportOpenDatabaseResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
{
    WebDatabase::observer()->reportOpenDatabaseResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
}

void DatabaseObserver::reportChangeVersionResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
{
    WebDatabase::observer()->reportChangeVersionResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
}

void DatabaseObserver::reportStartTransactionResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
{
    WebDatabase::observer()->reportStartTransactionResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
}

void DatabaseObserver::reportCommitTransactionResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
{
    WebDatabase::observer()->reportCommitTransactionResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
}

void DatabaseObserver::reportExecuteStatementResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
{
    WebDatabase::observer()->reportExecuteStatementResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
}

void DatabaseObserver::reportVacuumDatabaseResult(DatabaseBackendBase* database, int sqliteErrorCode)
{
    WebDatabase::observer()->reportVacuumDatabaseResult(WebDatabase(database), sqliteErrorCode);
}

} // namespace WebCore
