/*
 * Copyright (C) 2015-2021 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.
 */

#pragma once

#include "EventTarget.h"
#include "IDBActiveDOMObject.h"
#include "IDBError.h"
#include "IDBGetAllRecordsData.h"
#include "IDBGetRecordData.h"
#include "IDBKeyRangeData.h"
#include "IDBOpenDBRequest.h"
#include "IDBTransactionInfo.h"
#include "IDBTransactionMode.h"
#include "IndexedDB.h"
#include "Timer.h"
#include <wtf/Deque.h>
#include <wtf/HashMap.h>
#include <wtf/Lock.h>

namespace WebCore {

class DOMException;
class DOMStringList;
class IDBCursor;
class IDBCursorInfo;
class IDBDatabase;
class IDBIndex;
class IDBIndexInfo;
class IDBKey;
class IDBKeyData;
class IDBObjectStore;
class IDBObjectStoreInfo;
class IDBResultData;
class SerializedScriptValue;

struct IDBIterateCursorData;
struct IDBKeyRangeData;

namespace IDBClient {
class IDBConnectionProxy;
class TransactionOperation;
}

class IDBTransaction final : public ThreadSafeRefCounted<IDBTransaction>, public EventTargetWithInlineData, public IDBActiveDOMObject {
    WTF_MAKE_ISO_ALLOCATED_EXPORT(IDBTransaction, WEBCORE_EXPORT);
public:
    static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&);
    static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest&);

    static uint64_t generateOperationID();

    WEBCORE_EXPORT ~IDBTransaction() final;

    // IDBTransaction IDL
    Ref<DOMStringList> objectStoreNames() const;
    IDBTransactionMode mode() const { return m_info.mode(); }
    IDBTransactionDurability durability() const { return m_info.durability(); }
    IDBDatabase* db();
    DOMException* error() const;
    ExceptionOr<Ref<IDBObjectStore>> objectStore(const String& name);
    ExceptionOr<void> abort();
    ExceptionOr<void> commit();

    EventTargetInterface eventTargetInterface() const final { return IDBTransactionEventTargetInterfaceType; }
    ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
    void refEventTarget() final { ThreadSafeRefCounted::ref(); }
    void derefEventTarget() final { ThreadSafeRefCounted::deref(); }
    using EventTarget::dispatchEvent;
    void dispatchEvent(Event&) final;

    using ThreadSafeRefCounted<IDBTransaction>::ref;
    using ThreadSafeRefCounted<IDBTransaction>::deref;

    const IDBTransactionInfo& info() const { return m_info; }
    IDBDatabase& database() { return m_database.get(); }
    const IDBDatabase& database() const { return m_database.get(); }
    IDBDatabaseInfo* originalDatabaseInfo() const { return m_info.originalDatabaseInfo(); }

    void didStart(const IDBError&);
    void didAbort(const IDBError&);
    void didCommit(const IDBError&);

    bool isVersionChange() const { return mode() == IDBTransactionMode::Versionchange; }
    bool isReadOnly() const { return mode() == IDBTransactionMode::Readonly; }
    bool isActive() const;

    Ref<IDBObjectStore> createObjectStore(const IDBObjectStoreInfo&);
    void renameObjectStore(IDBObjectStore&, const String& newName);
    std::unique_ptr<IDBIndex> createIndex(IDBObjectStore&, const IDBIndexInfo&);
    void renameIndex(IDBIndex&, const String& newName);

    Ref<IDBRequest> requestPutOrAdd(IDBObjectStore&, RefPtr<IDBKey>&&, SerializedScriptValue&, IndexedDB::ObjectStoreOverwriteMode);
    Ref<IDBRequest> requestGetRecord(IDBObjectStore&, const IDBGetRecordData&);
    Ref<IDBRequest> requestGetAllObjectStoreRecords(IDBObjectStore&, const IDBKeyRangeData&, IndexedDB::GetAllType, std::optional<uint32_t> count);
    Ref<IDBRequest> requestGetAllIndexRecords(IDBIndex&, const IDBKeyRangeData&, IndexedDB::GetAllType, std::optional<uint32_t> count);
    Ref<IDBRequest> requestDeleteRecord(IDBObjectStore&, const IDBKeyRangeData&);
    Ref<IDBRequest> requestClearObjectStore(IDBObjectStore&);
    Ref<IDBRequest> requestCount(IDBObjectStore&, const IDBKeyRangeData&);
    Ref<IDBRequest> requestCount(IDBIndex&, const IDBKeyRangeData&);
    Ref<IDBRequest> requestGetValue(IDBIndex&, const IDBKeyRangeData&);
    Ref<IDBRequest> requestGetKey(IDBIndex&, const IDBKeyRangeData&);
    Ref<IDBRequest> requestOpenCursor(IDBObjectStore&, const IDBCursorInfo&);
    Ref<IDBRequest> requestOpenCursor(IDBIndex&, const IDBCursorInfo&);
    void iterateCursor(IDBCursor&, const IDBIterateCursorData&);

    void deleteObjectStore(const String& objectStoreName);
    void deleteIndex(uint64_t objectStoreIdentifier, const String& indexName);

    void addRequest(IDBRequest&);
    void removeRequest(IDBRequest&);

    void abortDueToFailedRequest(DOMException&);

    void activate();
    void deactivate();

    void operationCompletedOnServer(const IDBResultData&, IDBClient::TransactionOperation&);
    void operationCompletedOnClient(IDBClient::TransactionOperation&);

    void finishedDispatchEventForRequest(IDBRequest&);

    bool isFinishedOrFinishing() const;
    bool isFinished() const { return m_state == IndexedDB::TransactionState::Finished; }
    bool didDispatchAbortOrCommit() const { return m_didDispatchAbortOrCommit; }

    IDBClient::IDBConnectionProxy& connectionProxy();

    void connectionClosedFromServer(const IDBError&);

    template<typename Visitor> void visitReferencedObjectStores(Visitor&) const;

    WEBCORE_EXPORT static std::atomic<unsigned> numberOfIDBTransactions;

    // ActiveDOMObject.
    void stop() final;

private:
    IDBTransaction(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest*);

    // ActiveDOMObject.
    const char* activeDOMObjectName() const final;
    bool virtualHasPendingActivity() const final;

    void commitInternal();
    void abortInternal();
    void notifyDidAbort(const IDBError&);
    void finishAbortOrCommit();
    void abortInProgressOperations(const IDBError&);

    enum class IsWriteOperation : bool { No, Yes };
    void scheduleOperation(Ref<IDBClient::TransactionOperation>&&, IsWriteOperation = IsWriteOperation::No);
    void handleOperationsCompletedOnServer();
    void handlePendingOperations();
    void autoCommit();

    void fireOnComplete();
    void fireOnAbort();
    void enqueueEvent(Ref<Event>&&);

    Ref<IDBRequest> requestIndexRecord(IDBIndex&, IndexedDB::IndexRecordType, const IDBKeyRangeData&);

    void commitOnServer(IDBClient::TransactionOperation&, uint64_t pendingRequestCount);
    void abortOnServerAndCancelRequests(IDBClient::TransactionOperation&);

    void createObjectStoreOnServer(IDBClient::TransactionOperation&, const IDBObjectStoreInfo&);
    void didCreateObjectStoreOnServer(const IDBResultData&);

    void renameObjectStoreOnServer(IDBClient::TransactionOperation&, const uint64_t& objectStoreIdentifier, const String& newName);
    void didRenameObjectStoreOnServer(const IDBResultData&);

    void createIndexOnServer(IDBClient::TransactionOperation&, const IDBIndexInfo&);
    void didCreateIndexOnServer(const IDBResultData&);

    void renameIndexOnServer(IDBClient::TransactionOperation&, const uint64_t& objectStoreIdentifier, const uint64_t& indexIdentifier, const String& newName);
    void didRenameIndexOnServer(const IDBResultData&);

    void clearObjectStoreOnServer(IDBClient::TransactionOperation&, const uint64_t& objectStoreIdentifier);
    void didClearObjectStoreOnServer(IDBRequest&, const IDBResultData&);

    void putOrAddOnServer(IDBClient::TransactionOperation&, RefPtr<IDBKey>, RefPtr<SerializedScriptValue>, const IndexedDB::ObjectStoreOverwriteMode&);
    void didPutOrAddOnServer(IDBRequest&, const IDBResultData&);

    void getRecordOnServer(IDBClient::TransactionOperation&, const IDBGetRecordData&);
    void didGetRecordOnServer(IDBRequest&, const IDBResultData&);

    void getAllRecordsOnServer(IDBClient::TransactionOperation&, const IDBGetAllRecordsData&);
    void didGetAllRecordsOnServer(IDBRequest&, const IDBResultData&);

    void getCountOnServer(IDBClient::TransactionOperation&, const IDBKeyRangeData&);
    void didGetCountOnServer(IDBRequest&, const IDBResultData&);

    void deleteRecordOnServer(IDBClient::TransactionOperation&, const IDBKeyRangeData&);
    void didDeleteRecordOnServer(IDBRequest&, const IDBResultData&);

    void deleteObjectStoreOnServer(IDBClient::TransactionOperation&, const String& objectStoreName);
    void didDeleteObjectStoreOnServer(const IDBResultData&);

    void deleteIndexOnServer(IDBClient::TransactionOperation&, const uint64_t& objectStoreIdentifier, const String& indexName);
    void didDeleteIndexOnServer(const IDBResultData&);

    Ref<IDBRequest> doRequestOpenCursor(Ref<IDBCursor>&&);
    void openCursorOnServer(IDBClient::TransactionOperation&, const IDBCursorInfo&);
    void didOpenCursorOnServer(IDBRequest&, const IDBResultData&);

    void iterateCursorOnServer(IDBClient::TransactionOperation&, const IDBIterateCursorData&);
    void didIterateCursorOnServer(IDBRequest&, const IDBResultData&);

    void transitionedToFinishing(IndexedDB::TransactionState);

    void establishOnServer();

    void completeNoncursorRequest(IDBRequest&, const IDBResultData&);
    void completeCursorRequest(IDBRequest&, const IDBResultData&);

    void trySchedulePendingOperationTimer();

    Ref<IDBDatabase> m_database;
    IDBTransactionInfo m_info;

    IndexedDB::TransactionState m_state { IndexedDB::TransactionState::Inactive };
    bool m_startedOnServer { false };

    IDBError m_idbError;
    RefPtr<DOMException> m_domError;

    RefPtr<IDBOpenDBRequest> m_openDBRequest;

    Deque<RefPtr<IDBClient::TransactionOperation>> m_pendingTransactionOperationQueue;
    Deque<IDBClient::TransactionOperation*> m_transactionOperationsInProgressQueue;
    Deque<RefPtr<IDBClient::TransactionOperation>> m_abortQueue;
    Event* m_abortOrCommitEvent;
    HashMap<RefPtr<IDBClient::TransactionOperation>, IDBResultData> m_transactionOperationResultMap;
    HashMap<IDBResourceIdentifier, RefPtr<IDBClient::TransactionOperation>> m_transactionOperationMap;

    mutable Lock m_referencedObjectStoreLock;
    HashMap<String, std::unique_ptr<IDBObjectStore>> m_referencedObjectStores WTF_GUARDED_BY_LOCK(m_referencedObjectStoreLock);
    HashMap<uint64_t, std::unique_ptr<IDBObjectStore>> m_deletedObjectStores;

    HashSet<RefPtr<IDBRequest>> m_openRequests;
    RefPtr<IDBRequest> m_currentlyCompletingRequest;

    bool m_isStopped { false };
    bool m_didDispatchAbortOrCommit { false };

    uint64_t m_lastWriteOperationID { 0 };
    std::optional<IDBResourceIdentifier> m_lastTransactionOperationBeforeCommit;
    std::optional<IDBError> m_commitResult;
};

class TransactionActivator {
    WTF_MAKE_NONCOPYABLE(TransactionActivator);
public:
    TransactionActivator(IDBTransaction* transaction)
        : m_transaction(transaction)
    {
        if (m_transaction)
            m_transaction->activate();
    }

    ~TransactionActivator()
    {
        if (m_transaction)
            m_transaction->deactivate();
    }

private:
    IDBTransaction* m_transaction;
};

} // namespace WebCore
