/*
 * Copyright (C) 2015-2017 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "IDBRequest.h"

#if ENABLE(INDEXED_DATABASE)

#include "DOMException.h"
#include "Event.h"
#include "EventDispatcher.h"
#include "EventNames.h"
#include "EventQueue.h"
#include "IDBBindingUtilities.h"
#include "IDBConnectionProxy.h"
#include "IDBCursor.h"
#include "IDBDatabase.h"
#include "IDBIndex.h"
#include "IDBKeyData.h"
#include "IDBObjectStore.h"
#include "IDBResultData.h"
#include "JSDOMConvertIndexedDB.h"
#include "JSDOMConvertNumbers.h"
#include "JSDOMConvertSequences.h"
#include "Logging.h"
#include "ScriptExecutionContext.h"
#include "ThreadSafeDataBuffer.h"
#include <JavaScriptCore/StrongInlines.h>
#include <wtf/IsoMallocInlines.h>
#include <wtf/Scope.h>
#include <wtf/Variant.h>


namespace WebCore {
using namespace JSC;

WTF_MAKE_ISO_ALLOCATED_IMPL(IDBRequest);

Ref<IDBRequest> IDBRequest::create(ScriptExecutionContext& context, IDBObjectStore& objectStore, IDBTransaction& transaction)
{
    return adoptRef(*new IDBRequest(context, objectStore, transaction));
}

Ref<IDBRequest> IDBRequest::create(ScriptExecutionContext& context, IDBCursor& cursor, IDBTransaction& transaction)
{
    return adoptRef(*new IDBRequest(context, cursor, transaction));
}

Ref<IDBRequest> IDBRequest::create(ScriptExecutionContext& context, IDBIndex& index, IDBTransaction& transaction)
{
    return adoptRef(*new IDBRequest(context, index, transaction));
}

Ref<IDBRequest> IDBRequest::createObjectStoreGet(ScriptExecutionContext& context, IDBObjectStore& objectStore, IndexedDB::ObjectStoreRecordType type, IDBTransaction& transaction)
{
    return adoptRef(*new IDBRequest(context, objectStore, type, transaction));
}

Ref<IDBRequest> IDBRequest::createIndexGet(ScriptExecutionContext& context, IDBIndex& index, IndexedDB::IndexRecordType requestedRecordType, IDBTransaction& transaction)
{
    return adoptRef(*new IDBRequest(context, index, requestedRecordType, transaction));
}

IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBClient::IDBConnectionProxy& connectionProxy)
    : IDBActiveDOMObject(&context)
    , m_resourceIdentifier(connectionProxy)
    , m_connectionProxy(connectionProxy)
{
    m_result = NullResultType::Undefined;
    suspendIfNeeded();
}

IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBObjectStore& objectStore, IDBTransaction& transaction)
    : IDBActiveDOMObject(&context)
    , m_transaction(&transaction)
    , m_resourceIdentifier(transaction.connectionProxy())
    , m_source(&objectStore)
    , m_connectionProxy(transaction.database().connectionProxy())
{
    m_result = NullResultType::Undefined;
    suspendIfNeeded();
}

IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBCursor& cursor, IDBTransaction& transaction)
    : IDBActiveDOMObject(&context)
    , m_transaction(&transaction)
    , m_resourceIdentifier(transaction.connectionProxy())
    , m_pendingCursor(&cursor)
    , m_connectionProxy(transaction.database().connectionProxy())
{
    suspendIfNeeded();

    WTF::switchOn(cursor.source(),
        [this] (const auto& value) { this->m_source = IDBRequest::Source { value }; }
    );

    m_result = NullResultType::Undefined;
    cursor.setRequest(*this);
}

IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBIndex& index, IDBTransaction& transaction)
    : IDBActiveDOMObject(&context)
    , m_transaction(&transaction)
    , m_resourceIdentifier(transaction.connectionProxy())
    , m_source(&index)
    , m_connectionProxy(transaction.database().connectionProxy())
{
    m_result = NullResultType::Undefined;
    suspendIfNeeded();
}

IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBObjectStore& objectStore, IndexedDB::ObjectStoreRecordType type, IDBTransaction& transaction)
    : IDBActiveDOMObject(&context)
    , m_transaction(&transaction)
    , m_resourceIdentifier(transaction.connectionProxy())
    , m_source(&objectStore)
    , m_requestedObjectStoreRecordType(type)
    , m_connectionProxy(transaction.database().connectionProxy())
{
    m_result = NullResultType::Undefined;
    suspendIfNeeded();
}

IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBIndex& index, IndexedDB::IndexRecordType requestedRecordType, IDBTransaction& transaction)
    : IDBRequest(context, index, transaction)
{
    m_result = NullResultType::Undefined;
    m_requestedIndexRecordType = requestedRecordType;
}

IDBRequest::~IDBRequest()
{
    ASSERT(&originThread() == &Thread::current());

    WTF::switchOn(m_result,
        [] (RefPtr<IDBCursor>& cursor) { cursor->clearRequest(); },
        [] (const auto&) { }
    );
}

ExceptionOr<IDBRequest::Result> IDBRequest::result() const
{
    if (!isDone())
        return Exception { InvalidStateError, "Failed to read the 'result' property from 'IDBRequest': The request has not finished."_s };

    return IDBRequest::Result { m_result };
}

ExceptionOr<DOMException*> IDBRequest::error() const
{
    ASSERT(&originThread() == &Thread::current());

    if (!isDone())
        return Exception { InvalidStateError, "Failed to read the 'error' property from 'IDBRequest': The request has not finished."_s };

    return m_domError.get();
}

void IDBRequest::setSource(IDBCursor& cursor)
{
    ASSERT(&originThread() == &Thread::current());

    m_source = Source { &cursor };
}

void IDBRequest::setVersionChangeTransaction(IDBTransaction& transaction)
{
    ASSERT(&originThread() == &Thread::current());
    ASSERT(!m_transaction);
    ASSERT(transaction.isVersionChange());
    ASSERT(!transaction.isFinishedOrFinishing());

    m_transaction = &transaction;
}

RefPtr<WebCore::IDBTransaction> IDBRequest::transaction() const
{
    ASSERT(&originThread() == &Thread::current());
    return m_shouldExposeTransactionToDOM ? m_transaction : nullptr;
}

uint64_t IDBRequest::sourceObjectStoreIdentifier() const
{
    ASSERT(&originThread() == &Thread::current());

    if (!m_source)
        return 0;

    return WTF::switchOn(m_source.value(),
        [] (const RefPtr<IDBObjectStore>& objectStore) { return objectStore->info().identifier(); },
        [] (const RefPtr<IDBIndex>& index) { return index->info().objectStoreIdentifier(); },
        [] (const RefPtr<IDBCursor>&) { return 0; }
    );
}

uint64_t IDBRequest::sourceIndexIdentifier() const
{
    ASSERT(&originThread() == &Thread::current());

    if (!m_source)
        return 0;

    return WTF::switchOn(m_source.value(),
        [] (const RefPtr<IDBObjectStore>&) -> uint64_t { return 0; },
        [] (const RefPtr<IDBIndex>& index) -> uint64_t { return index->info().identifier(); },
        [] (const RefPtr<IDBCursor>&) -> uint64_t { return 0; }
    );
}

IndexedDB::ObjectStoreRecordType IDBRequest::requestedObjectStoreRecordType() const
{
    ASSERT(&originThread() == &Thread::current());

    return m_requestedObjectStoreRecordType;
}

IndexedDB::IndexRecordType IDBRequest::requestedIndexRecordType() const
{
    ASSERT(&originThread() == &Thread::current());
    ASSERT(m_source);
    ASSERT(WTF::holds_alternative<RefPtr<IDBIndex>>(m_source.value()));

    return m_requestedIndexRecordType;
}

EventTargetInterface IDBRequest::eventTargetInterface() const
{
    ASSERT(&originThread() == &Thread::current());

    return IDBRequestEventTargetInterfaceType;
}

const char* IDBRequest::activeDOMObjectName() const
{
    ASSERT(&originThread() == &Thread::current());

    return "IDBRequest";
}

bool IDBRequest::canSuspendForDocumentSuspension() const
{
    ASSERT(&originThread() == &Thread::current());
    return true;
}

bool IDBRequest::hasPendingActivity() const
{
    ASSERT(&originThread() == &Thread::current() || Thread::mayBeGCThread());
    return !m_contextStopped && m_hasPendingActivity;
}

void IDBRequest::stop()
{
    ASSERT(&originThread() == &Thread::current());
    ASSERT(!m_contextStopped);

    cancelForStop();

    removeAllEventListeners();

    clearWrappers();

    m_contextStopped = true;
}

void IDBRequest::cancelForStop()
{
    // The base IDBRequest class has nothing additional to do here.
}

void IDBRequest::enqueueEvent(Ref<Event>&& event)
{
    ASSERT(&originThread() == &Thread::current());
    if (m_contextStopped)
        return;

    event->setTarget(this);
    scriptExecutionContext()->eventQueue().enqueueEvent(WTFMove(event));
}

void IDBRequest::dispatchEvent(Event& event)
{
    LOG(IndexedDB, "IDBRequest::dispatchEvent - %s (%p)", event.type().string().utf8().data(), this);

    ASSERT(&originThread() == &Thread::current());
    ASSERT(m_hasPendingActivity);
    ASSERT(!m_contextStopped);

    auto protectedThis = makeRef(*this);
    m_dispatchingEvent = true;

    if (event.type() != eventNames().blockedEvent)
        m_readyState = ReadyState::Done;

    Vector<EventTarget*> targets { this };

    if (&event == m_openDatabaseSuccessEvent)
        m_openDatabaseSuccessEvent = nullptr;
    else if (m_transaction && !m_transaction->didDispatchAbortOrCommit())
        targets = { this, m_transaction.get(), &m_transaction->database() };

    m_hasPendingActivity = false;

    {
        TransactionActivator activator(m_transaction.get());
        EventDispatcher::dispatchEvent(targets, event);
    }

    // Dispatching the event might have set the pending activity flag back to true, suggesting the request will be reused.
    // We might also re-use the request if this event was the upgradeneeded event for an IDBOpenDBRequest.
    if (!m_hasPendingActivity)
        m_hasPendingActivity = isOpenDBRequest() && (event.type() == eventNames().upgradeneededEvent || event.type() == eventNames().blockedEvent);

    m_dispatchingEvent = false;
    if (!m_transaction)
        return;

    // The request should only remain in the transaction's request list if it represents a pending cursor operation, or this is an open request that was blocked.
    if (!m_pendingCursor && event.type() != eventNames().blockedEvent)
        m_transaction->removeRequest(*this);

    if (m_hasUncaughtException)
        m_transaction->abortDueToFailedRequest(DOMException::create(AbortError, "IDBTransaction will abort due to uncaught exception in an event handler"_s));
    else if (!event.defaultPrevented() && event.type() == eventNames().errorEvent && !m_transaction->isFinishedOrFinishing()) {
        ASSERT(m_domError);
        m_transaction->abortDueToFailedRequest(*m_domError);
    }

    m_transaction->finishedDispatchEventForRequest(*this);
}

void IDBRequest::uncaughtExceptionInEventHandler()
{
    LOG(IndexedDB, "IDBRequest::uncaughtExceptionInEventHandler");

    ASSERT(&originThread() == &Thread::current());

    if (m_dispatchingEvent) {
        ASSERT(!m_hasUncaughtException);
        m_hasUncaughtException = true;
        return;
    }
    if (m_transaction && m_idbError.code() != AbortError)
        m_transaction->abortDueToFailedRequest(DOMException::create(AbortError, "IDBTransaction will abort due to uncaught exception in an event handler"_s));
}

void IDBRequest::setResult(const IDBKeyData& keyData)
{
    ASSERT(&originThread() == &Thread::current());

    auto* context = scriptExecutionContext();
    if (!context)
        return;

    VM& vm = context->vm();
    JSLockHolder lock(vm);
    m_result = keyData;
    m_resultWrapper = { };
}

void IDBRequest::setResult(const Vector<IDBKeyData>& keyDatas)
{
    ASSERT(&originThread() == &Thread::current());

    auto* context = scriptExecutionContext();
    if (!context)
        return;

    VM& vm = context->vm();
    JSLockHolder lock(vm);
    m_result = keyDatas;
    m_resultWrapper = { };
}

void IDBRequest::setResult(const IDBGetAllResult& result)
{
    ASSERT(&originThread() == &Thread::current());

    auto* context = scriptExecutionContext();
    if (!context)
        return;

    VM& vm = context->vm();
    JSLockHolder lock(vm);
    m_result = result;
    m_resultWrapper = { };
}

void IDBRequest::setResult(uint64_t number)
{
    ASSERT(&originThread() == &Thread::current());

    auto* context = scriptExecutionContext();
    if (!context)
        return;

    VM& vm = context->vm();
    JSLockHolder lock(vm);
    m_result = number;
    m_resultWrapper = { };
}

void IDBRequest::setResultToStructuredClone(const IDBGetResult& result)
{
    ASSERT(&originThread() == &Thread::current());

    LOG(IndexedDB, "IDBRequest::setResultToStructuredClone");

    auto* context = scriptExecutionContext();
    if (!context)
        return;

    VM& vm = context->vm();
    JSLockHolder lock(vm);
    m_result = result;
    m_resultWrapper = { };
}

void IDBRequest::setResultToUndefined()
{
    ASSERT(&originThread() == &Thread::current());

    auto* context = scriptExecutionContext();
    if (!context)
        return;
    
    VM& vm = context->vm();
    JSLockHolder lock(vm);
    m_result = NullResultType::Undefined;
    m_resultWrapper = { };
}

IDBCursor* IDBRequest::resultCursor()
{
    ASSERT(&originThread() == &Thread::current());

    return WTF::switchOn(m_result,
        [] (const RefPtr<IDBCursor>& cursor) -> IDBCursor* { return cursor.get(); },
        [] (const auto&) -> IDBCursor* { return nullptr; }
    );
}

void IDBRequest::willIterateCursor(IDBCursor& cursor)
{
    ASSERT(&originThread() == &Thread::current());
    ASSERT(isDone());
    ASSERT(scriptExecutionContext());
    ASSERT(m_transaction);
    ASSERT(!m_pendingCursor);
    ASSERT(&cursor == resultCursor());

    m_pendingCursor = &cursor;
    m_hasPendingActivity = true;
    m_result = NullResultType::Empty;

    auto* context = scriptExecutionContext();
    if (!context)
        return;

    VM& vm = context->vm();
    JSLockHolder lock(vm);

    if (m_resultWrapper)
        m_cursorWrapper = m_resultWrapper;
    m_resultWrapper = { };
    m_readyState = ReadyState::Pending;
    m_domError = nullptr;
    m_idbError = IDBError { };
}

void IDBRequest::didOpenOrIterateCursor(const IDBResultData& resultData)
{
    ASSERT(&originThread() == &Thread::current());
    ASSERT(m_pendingCursor);

    auto* context = scriptExecutionContext();
    if (!context)
        return;

    VM& vm = context->vm();
    JSLockHolder lock(vm);

    m_result = NullResultType::Empty;
    m_resultWrapper = { };

    if (resultData.type() == IDBResultType::IterateCursorSuccess || resultData.type() == IDBResultType::OpenCursorSuccess) {
        if (m_pendingCursor->setGetResult(*this, resultData.getResult()) && m_cursorWrapper)
            m_resultWrapper = m_cursorWrapper;
        if (resultData.getResult().isDefined())
            m_result = m_pendingCursor;
    }

    m_pendingCursor = nullptr;

    completeRequestAndDispatchEvent(resultData);
}

void IDBRequest::completeRequestAndDispatchEvent(const IDBResultData& resultData)
{
    ASSERT(&originThread() == &Thread::current());

    m_readyState = ReadyState::Done;

    m_idbError = resultData.error();
    if (!m_idbError.isNull())
        onError();
    else
        onSuccess();
}

void IDBRequest::onError()
{
    LOG(IndexedDB, "IDBRequest::onError");

    ASSERT(&originThread() == &Thread::current());
    ASSERT(!m_idbError.isNull());

    m_domError = m_idbError.toDOMException();
    enqueueEvent(Event::create(eventNames().errorEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes));
}

void IDBRequest::onSuccess()
{
    LOG(IndexedDB, "IDBRequest::onSuccess");
    ASSERT(&originThread() == &Thread::current());
    enqueueEvent(Event::create(eventNames().successEvent, Event::CanBubble::No, Event::IsCancelable::No));
}

void IDBRequest::setResult(Ref<IDBDatabase>&& database)
{
    ASSERT(&originThread() == &Thread::current());

    auto* context = scriptExecutionContext();
    if (!context)
        return;

    VM& vm = context->vm();
    JSLockHolder lock(vm);

    m_result = RefPtr<IDBDatabase> { WTFMove(database) };
    m_resultWrapper = { };
}

void IDBRequest::clearWrappers()
{
    auto* context = scriptExecutionContext();
    if (!context)
        return;
    VM& vm = context->vm();
    JSLockHolder lock(vm);
    
    m_resultWrapper.clear();
    m_cursorWrapper.clear();
    
    WTF::switchOn(m_result,
        [] (RefPtr<IDBCursor>& cursor) { cursor->clearWrappers(); },
        [] (const auto&) { }
    );
}


} // namespace WebCore

#endif // ENABLE(INDEXED_DATABASE)
