/*
 * Copyright (C) 2007, 2008, 2013 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 "modules/webdatabase/SQLTransactionBackend.h"

#include "modules/webdatabase/Database.h"
#include "modules/webdatabase/DatabaseAuthorizer.h"
#include "modules/webdatabase/DatabaseContext.h"
#include "modules/webdatabase/DatabaseThread.h"
#include "modules/webdatabase/DatabaseTracker.h"
#include "modules/webdatabase/SQLError.h"
#include "modules/webdatabase/SQLStatementBackend.h"
#include "modules/webdatabase/SQLTransaction.h"
#include "modules/webdatabase/SQLTransactionClient.h"
#include "modules/webdatabase/SQLTransactionCoordinator.h"
#include "modules/webdatabase/StorageLog.h"
#include "modules/webdatabase/sqlite/SQLValue.h"
#include "modules/webdatabase/sqlite/SQLiteTransaction.h"
#include "wtf/PtrUtil.h"
#include "wtf/StdLibExtras.h"
#include <memory>

// How does a SQLTransaction work?
// ==============================
// The SQLTransaction is a state machine that executes a series of states /
// steps.
//
// The work of the transaction states are defined in section of 4.3.2 of the
// webdatabase spec: http://dev.w3.org/html5/webdatabase/#processing-model
//
// the State Transition Graph at a glance:
// ======================================
//
//     Backend                        .   Frontend
//     (works with SQLiteDatabase)    .   (works with Script)
//     ===========================    .   ===================
//                                    .
//     1. Idle                        .
//         v                          .
//     2. AcquireLock                 .
//         v                          .
//     3. OpenTransactionAndPreflight -----------------------------------.
//         |                        .                                    |
//         `-------------------------> 8. DeliverTransactionCallback --. |
//                                  .     |                           v v
//         ,------------------------------' 9. DeliverTransactionErrorCallback +
//         |                        .                                  ^ ^ ^   |
//         v                        .                                  | | |   |
//     4. RunStatements -----------------------------------------------' | |   |
//         |        ^  ^ |  ^ |     .                                    | |   |
//         |--------'  | |  | `------> 10. DeliverStatementCallback +----' |   |
//         |           | |  `---------------------------------------'      |   |
//         |           | `-----------> 11. DeliverQuotaIncreaseCallback +  |   |
//         |            `-----------------------------------------------'  |   |
//         v                        .                                      |   |
//     5. PostflightAndCommit --+------------------------------------------'   |
//                              |----> 12. DeliverSuccessCallback +            |
//         ,--------------------'   .                             |            |
//         v                        .                             |            |
//     6. CleanupAndTerminate <-----------------------------------'            |
//         v           ^            .                                          |
//     0. End          |            .                                          |
//                     |            .                                          |
//                7: CleanupAfterTransactionErrorCallback <--------------------'
//                                  .
//
// the States and State Transitions:
// ================================
//     0. SQLTransactionState::End
//         - the end state.
//
//     1. SQLTransactionState::Idle
//         - placeholder state while waiting on frontend/backend, etc. See
//           comment on "State transitions between SQLTransaction and
//           SQLTransactionBackend" below.
//
//     2. SQLTransactionState::AcquireLock (runs in backend)
//         - this is the start state.
//         - acquire the "lock".
//         - on "lock" acquisition, goto
//           SQLTransactionState::OpenTransactionAndPreflight.
//
//     3. SQLTransactionState::openTransactionAndPreflight (runs in backend)
//         - Sets up an SQLiteTransaction.
//         - begin the SQLiteTransaction.
//         - call the SQLTransactionWrapper preflight if available.
//         - schedule script callback.
//         - on error, goto
//           SQLTransactionState::DeliverTransactionErrorCallback.
//         - goto SQLTransactionState::DeliverTransactionCallback.
//
//     4. SQLTransactionState::DeliverTransactionCallback (runs in frontend)
//         - invoke the script function callback() if available.
//         - on error, goto
//           SQLTransactionState::DeliverTransactionErrorCallback.
//         - goto SQLTransactionState::RunStatements.
//
//     5. SQLTransactionState::DeliverTransactionErrorCallback (runs in
//        frontend)
//         - invoke the script function errorCallback if available.
//         - goto SQLTransactionState::CleanupAfterTransactionErrorCallback.
//
//     6. SQLTransactionState::RunStatements (runs in backend)
//         - while there are statements {
//             - run a statement.
//             - if statementCallback is available, goto
//               SQLTransactionState::DeliverStatementCallback.
//             - on error,
//               goto SQLTransactionState::DeliverQuotaIncreaseCallback, or
//               goto SQLTransactionState::DeliverStatementCallback, or
//               goto SQLTransactionState::deliverTransactionErrorCallback.
//           }
//         - goto SQLTransactionState::PostflightAndCommit.
//
//     7. SQLTransactionState::DeliverStatementCallback (runs in frontend)
//         - invoke script statement callback (assume available).
//         - on error, goto
//           SQLTransactionState::DeliverTransactionErrorCallback.
//         - goto SQLTransactionState::RunStatements.
//
//     8. SQLTransactionState::DeliverQuotaIncreaseCallback (runs in frontend)
//         - give client a chance to increase the quota.
//         - goto SQLTransactionState::RunStatements.
//
//     9. SQLTransactionState::PostflightAndCommit (runs in backend)
//         - call the SQLTransactionWrapper postflight if available.
//         - commit the SQLiteTansaction.
//         - on error, goto
//           SQLTransactionState::DeliverTransactionErrorCallback.
//         - if successCallback is available, goto
//           SQLTransactionState::DeliverSuccessCallback.
//           else goto SQLTransactionState::CleanupAndTerminate.
//
//     10. SQLTransactionState::DeliverSuccessCallback (runs in frontend)
//         - invoke the script function successCallback() if available.
//         - goto SQLTransactionState::CleanupAndTerminate.
//
//     11. SQLTransactionState::CleanupAndTerminate (runs in backend)
//         - stop and clear the SQLiteTransaction.
//         - release the "lock".
//         - goto SQLTransactionState::End.
//
//     12. SQLTransactionState::CleanupAfterTransactionErrorCallback (runs in
//         backend)
//         - rollback the SQLiteTransaction.
//         - goto SQLTransactionState::CleanupAndTerminate.
//
// State transitions between SQLTransaction and SQLTransactionBackend
// ==================================================================
// As shown above, there are state transitions that crosses the boundary between
// the frontend and backend. For example,
//
//     OpenTransactionAndPreflight (state 3 in the backend)
//     transitions to DeliverTransactionCallback (state 8 in the frontend),
//     which in turn transitions to RunStatements (state 4 in the backend).
//
// This cross boundary transition is done by posting transition requests to the
// other side and letting the other side's state machine execute the state
// transition in the appropriate thread (i.e. the script thread for the
// frontend, and the database thread for the backend).
//
// Logically, the state transitions work as shown in the graph above. But
// physically, the transition mechanism uses the Idle state (both in the
// frontend and backend) as a waiting state for further activity. For example,
// taking a closer look at the 3 state transition example above, what actually
// happens is as follows:
//
//     Step 1:
//     ======
//     In the frontend thread:
//     - waiting quietly is Idle. Not doing any work.
//
//     In the backend:
//     - is in OpenTransactionAndPreflight, and doing its work.
//     - when done, it transits to the backend DeliverTransactionCallback.
//     - the backend DeliverTransactionCallback sends a request to the frontend
//       to transit to DeliverTransactionCallback, and then itself transits to
//       Idle.
//
//     Step 2:
//     ======
//     In the frontend thread:
//     - transits to DeliverTransactionCallback and does its work.
//     - when done, it transits to the frontend RunStatements.
//     - the frontend RunStatements sends a request to the backend to transit
//       to RunStatements, and then itself transits to Idle.
//
//     In the backend:
//     - waiting quietly in Idle.
//
//     Step 3:
//     ======
//     In the frontend thread:
//     - waiting quietly is Idle. Not doing any work.
//
//     In the backend:
//     - transits to RunStatements, and does its work.
//        ...
//
// So, when the frontend or backend are not active, they will park themselves in
// their Idle states. This means their m_nextState is set to Idle, but they
// never actually run the corresponding state function. Note: for both the
// frontend and backend, the state function for Idle is unreachableState().
//
// The states that send a request to their peer across the front/back boundary
// are implemented with just 2 functions: SQLTransaction::sendToBackendState()
// and SQLTransactionBackend::sendToFrontendState(). These state functions do
// nothing but sends a request to the other side to transit to the current
// state (indicated by m_nextState), and then transits itself to the Idle state
// to wait for further action.

// The Life-Cycle of a SQLTransaction i.e. Who's keeping the SQLTransaction
// alive?
// ==============================================================================
// The RefPtr chain goes something like this:
//
//     At birth (in Database::runTransaction()):
//     ====================================================
//     Database
//         // HeapDeque<Member<SQLTransactionBackend>> m_transactionQueue
//         // points to ...
//     --> SQLTransactionBackend
//         // Member<SQLTransaction> m_frontend points to ...
//     --> SQLTransaction
//         // Member<SQLTransactionBackend> m_backend points to ...
//     --> SQLTransactionBackend  // which is a circular reference.
//
//     Note: there's a circular reference between the SQLTransaction front-end
//     and back-end. This circular reference is established in the constructor
//     of the SQLTransactionBackend. The circular reference will be broken by
//     calling doCleanup() to nullify m_frontend. This is done at the end of the
//     transaction's clean up state (i.e. when the transaction should no longer
//     be in use thereafter), or if the database was interrupted. See comments
//     on "What happens if a transaction is interrupted?" below for details.
//
//     After scheduling the transaction with the DatabaseThread
//     (Database::scheduleTransaction()):
//     ======================================================================================================
//     DatabaseThread
//         // MessageQueue<DatabaseTask> m_queue points to ...
//     --> DatabaseTransactionTask
//         // Member<SQLTransactionBackend> m_transaction points to ...
//     --> SQLTransactionBackend
//         // Member<SQLTransaction> m_frontend points to ...
//     --> SQLTransaction
//         // Member<SQLTransactionBackend> m_backend points to ...
//     --> SQLTransactionBackend  // which is a circular reference.
//
//     When executing the transaction (in DatabaseThread::databaseThread()):
//     ====================================================================
//     std::unique_ptr<DatabaseTask> task;
//         // points to ...
//     --> DatabaseTransactionTask
//         // Member<SQLTransactionBackend> m_transaction points to ...
//     --> SQLTransactionBackend
//         // Member<SQLTransaction> m_frontend;
//     --> SQLTransaction
//         // Member<SQLTransactionBackend> m_backend points to ...
//     --> SQLTransactionBackend  // which is a circular reference.
//
//     At the end of cleanupAndTerminate():
//     ===================================
//     At the end of the cleanup state, the SQLTransactionBackend::m_frontend is
//     nullified.  If by then, a JSObject wrapper is referring to the
//     SQLTransaction, then the reference chain looks like this:
//
//     JSObjectWrapper
//     --> SQLTransaction
//         // in Member<SQLTransactionBackend> m_backend points to ...
//     --> SQLTransactionBackend
//         // which no longer points back to its SQLTransaction.
//
//     When the GC collects the corresponding JSObject, the above chain will be
//     cleaned up and deleted.
//
//     If there is no JSObject wrapper referring to the SQLTransaction when the
//     cleanup states nullify SQLTransactionBackend::m_frontend, the
//     SQLTransaction will deleted then.  However, there will still be a
//     DatabaseTask pointing to the SQLTransactionBackend (see the "When
//     executing the transaction" chain above). This will keep the
//     SQLTransactionBackend alive until DatabaseThread::databaseThread()
//     releases its task std::unique_ptr.
//
//     What happens if a transaction is interrupted?
//     ============================================
//     If the transaction is interrupted half way, it won't get to run to state
//     CleanupAndTerminate, and hence, would not have called
//     SQLTransactionBackend's doCleanup(). doCleanup() is where we nullify
//     SQLTransactionBackend::m_frontend to break the reference cycle between
//     the frontend and backend. Hence, we need to cleanup the transaction by
//     other means.
//
//     Note: calling SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown()
//     is effectively the same as calling SQLTransactionBackend::doClean().
//
//     In terms of who needs to call doCleanup(), there are 5 phases in the
//     SQLTransactionBackend life-cycle. These are the phases and how the clean
//     up is done:
//
//     Phase 1. After Birth, before scheduling
//
//     - To clean up, DatabaseThread::databaseThread() will call
//       Database::close() during its shutdown.
//     - Database::close() will iterate
//       Database::m_transactionQueue and call
//       notifyDatabaseThreadIsShuttingDown() on each transaction there.
//
//     Phase 2. After scheduling, before state AcquireLock
//
//     - If the interruption occures before the DatabaseTransactionTask is
//       scheduled in DatabaseThread::m_queue but hasn't gotten to execute
//       (i.e. DatabaseTransactionTask::performTask() has not been called),
//       then the DatabaseTransactionTask may get destructed before it ever
//       gets to execute.
//     - To clean up, the destructor will check if the task's m_wasExecuted is
//       set. If not, it will call notifyDatabaseThreadIsShuttingDown() on
//       the task's transaction.
//
//     Phase 3. After state AcquireLock, before "lockAcquired"
//
//     - In this phase, the transaction would have been added to the
//       SQLTransactionCoordinator's CoordinationInfo's pendingTransactions.
//     - To clean up, during shutdown, DatabaseThread::databaseThread() calls
//       SQLTransactionCoordinator::shutdown(), which calls
//       notifyDatabaseThreadIsShuttingDown().
//
//     Phase 4: After "lockAcquired", before state CleanupAndTerminate
//
//     - In this phase, the transaction would have been added either to the
//       SQLTransactionCoordinator's CoordinationInfo's activeWriteTransaction
//       or activeReadTransactions.
//     - To clean up, during shutdown, DatabaseThread::databaseThread() calls
//       SQLTransactionCoordinator::shutdown(), which calls
//       notifyDatabaseThreadIsShuttingDown().
//
//     Phase 5: After state CleanupAndTerminate
//
//     - This is how a transaction ends normally.
//     - state CleanupAndTerminate calls doCleanup().

namespace blink {

SQLTransactionBackend* SQLTransactionBackend::create(
    Database* db,
    SQLTransaction* frontend,
    SQLTransactionWrapper* wrapper,
    bool readOnly) {
  return new SQLTransactionBackend(db, frontend, wrapper, readOnly);
}

SQLTransactionBackend::SQLTransactionBackend(Database* db,
                                             SQLTransaction* frontend,
                                             SQLTransactionWrapper* wrapper,
                                             bool readOnly)
    : m_frontend(frontend),
      m_database(db),
      m_wrapper(wrapper),
      m_hasCallback(m_frontend->hasCallback()),
      m_hasSuccessCallback(m_frontend->hasSuccessCallback()),
      m_hasErrorCallback(m_frontend->hasErrorCallback()),
      m_shouldRetryCurrentStatement(false),
      m_modifiedDatabase(false),
      m_lockAcquired(false),
      m_readOnly(readOnly),
      m_hasVersionMismatch(false) {
  DCHECK(isMainThread());
  ASSERT(m_database);
  m_frontend->setBackend(this);
  m_requestedState = SQLTransactionState::AcquireLock;
}

SQLTransactionBackend::~SQLTransactionBackend() {
  ASSERT(!m_sqliteTransaction);
}

DEFINE_TRACE(SQLTransactionBackend) {
  visitor->trace(m_database);
  visitor->trace(m_wrapper);
}

void SQLTransactionBackend::doCleanup() {
  if (!m_frontend)
    return;
  // Break the reference cycle. See comment about the life-cycle above.
  m_frontend = nullptr;

  ASSERT(
      database()->getDatabaseContext()->databaseThread()->isDatabaseThread());

  MutexLocker locker(m_statementMutex);
  m_statementQueue.clear();

  if (m_sqliteTransaction) {
    // In the event we got here because of an interruption or error (i.e. if
    // the transaction is in progress), we should roll it back here. Clearing
    // m_sqliteTransaction invokes SQLiteTransaction's destructor which does
    // just that. We might as well do this unconditionally and free up its
    // resources because we're already terminating.
    m_sqliteTransaction.reset();
  }

  // Release the lock on this database
  if (m_lockAcquired)
    m_database->transactionCoordinator()->releaseLock(this);

  // Do some aggresive clean up here except for m_database.
  //
  // We can't clear m_database here because the frontend may asynchronously
  // invoke SQLTransactionBackend::requestTransitToState(), and that function
  // uses m_database to schedule a state transition. This may occur because
  // the frontend (being in another thread) may already be on the way to
  // requesting our next state before it detects an interruption.
  //
  // There is no harm in letting it finish making the request. It'll set
  // m_requestedState, but we won't execute a transition to that state because
  // we've already shut down the transaction.
  //
  // We also can't clear m_currentStatementBackend and m_transactionError.
  // m_currentStatementBackend may be accessed asynchronously by the
  // frontend's deliverStatementCallback() state. Similarly,
  // m_transactionError may be accessed by deliverTransactionErrorCallback().
  // This occurs if requests for transition to those states have already been
  // registered with the frontend just prior to a clean up request arriving.
  //
  // So instead, let our destructor handle their clean up since this
  // SQLTransactionBackend is guaranteed to not destruct until the frontend
  // is also destructing.

  m_wrapper = nullptr;
}

SQLStatement* SQLTransactionBackend::currentStatement() {
  return m_currentStatementBackend->frontend();
}

SQLErrorData* SQLTransactionBackend::transactionError() {
  return m_transactionError.get();
}

void SQLTransactionBackend::setShouldRetryCurrentStatement(bool shouldRetry) {
  ASSERT(!m_shouldRetryCurrentStatement);
  m_shouldRetryCurrentStatement = shouldRetry;
}

SQLTransactionBackend::StateFunction SQLTransactionBackend::stateFunctionFor(
    SQLTransactionState state) {
  static const StateFunction stateFunctions[] = {
      &SQLTransactionBackend::unreachableState,                      // 0. end
      &SQLTransactionBackend::unreachableState,                      // 1. idle
      &SQLTransactionBackend::acquireLock,                           // 2.
      &SQLTransactionBackend::openTransactionAndPreflight,           // 3.
      &SQLTransactionBackend::runStatements,                         // 4.
      &SQLTransactionBackend::postflightAndCommit,                   // 5.
      &SQLTransactionBackend::cleanupAndTerminate,                   // 6.
      &SQLTransactionBackend::cleanupAfterTransactionErrorCallback,  // 7.
      // 8. deliverTransactionCallback
      &SQLTransactionBackend::sendToFrontendState,
      // 9. deliverTransactionErrorCallback
      &SQLTransactionBackend::sendToFrontendState,
      // 10.  deliverStatementCallback
      &SQLTransactionBackend::sendToFrontendState,
      // 11. deliverQuotaIncreaseCallback
      &SQLTransactionBackend::sendToFrontendState,
      // 12. deliverSuccessCallback
      &SQLTransactionBackend::sendToFrontendState,
  };

  ASSERT(WTF_ARRAY_LENGTH(stateFunctions) ==
         static_cast<int>(SQLTransactionState::NumberOfStates));
  ASSERT(state < SQLTransactionState::NumberOfStates);

  return stateFunctions[static_cast<int>(state)];
}

void SQLTransactionBackend::enqueueStatementBackend(
    SQLStatementBackend* statementBackend) {
  DCHECK(isMainThread());
  MutexLocker locker(m_statementMutex);
  m_statementQueue.append(statementBackend);
}

void SQLTransactionBackend::computeNextStateAndCleanupIfNeeded() {
  DCHECK(
      database()->getDatabaseContext()->databaseThread()->isDatabaseThread());
  // Only honor the requested state transition if we're not supposed to be
  // cleaning up and shutting down:
  if (m_database->opened()) {
    setStateToRequestedState();
    ASSERT(m_nextState == SQLTransactionState::AcquireLock ||
           m_nextState == SQLTransactionState::OpenTransactionAndPreflight ||
           m_nextState == SQLTransactionState::RunStatements ||
           m_nextState == SQLTransactionState::PostflightAndCommit ||
           m_nextState == SQLTransactionState::CleanupAndTerminate ||
           m_nextState ==
               SQLTransactionState::CleanupAfterTransactionErrorCallback);
#if DCHECK_IS_ON()
    STORAGE_DVLOG(1) << "State " << nameForSQLTransactionState(m_nextState);
#endif
    return;
  }

  // If we get here, then we should be shutting down. Do clean up if needed:
  if (m_nextState == SQLTransactionState::End)
    return;
  m_nextState = SQLTransactionState::End;

  // If the database was stopped, don't do anything and cancel queued work
  STORAGE_DVLOG(1) << "Database was stopped or interrupted - cancelling work "
                      "for this transaction";

  // The current SQLite transaction should be stopped, as well
  if (m_sqliteTransaction) {
    m_sqliteTransaction->stop();
    m_sqliteTransaction.reset();
  }

  // Terminate the frontend state machine. This also gets the frontend to
  // call computeNextStateAndCleanupIfNeeded() and clear its wrappers
  // if needed.
  m_frontend->requestTransitToState(SQLTransactionState::End);

  // Redirect to the end state to abort, clean up, and end the transaction.
  doCleanup();
}

void SQLTransactionBackend::performNextStep() {
  computeNextStateAndCleanupIfNeeded();
  runStateMachine();
}

void SQLTransactionBackend::executeSQL(SQLStatement* statement,
                                       const String& sqlStatement,
                                       const Vector<SQLValue>& arguments,
                                       int permissions) {
  DCHECK(isMainThread());
  enqueueStatementBackend(SQLStatementBackend::create(statement, sqlStatement,
                                                      arguments, permissions));
}

void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown() {
  ASSERT(
      database()->getDatabaseContext()->databaseThread()->isDatabaseThread());

  // If the transaction is in progress, we should roll it back here, since this
  // is our last opportunity to do something related to this transaction on the
  // DB thread. Amongst other work, doCleanup() will clear m_sqliteTransaction
  // which invokes SQLiteTransaction's destructor, which will do the roll back
  // if necessary.
  doCleanup();
}

SQLTransactionState SQLTransactionBackend::acquireLock() {
  m_database->transactionCoordinator()->acquireLock(this);
  return SQLTransactionState::Idle;
}

void SQLTransactionBackend::lockAcquired() {
  m_lockAcquired = true;
  requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight);
}

SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight() {
  DCHECK(
      database()->getDatabaseContext()->databaseThread()->isDatabaseThread());
  ASSERT(!m_database->sqliteDatabase().transactionInProgress());
  ASSERT(m_lockAcquired);

  STORAGE_DVLOG(1) << "Opening and preflighting transaction " << this;

  // Set the maximum usage for this transaction if this transactions is not
  // read-only.
  if (!m_readOnly)
    m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());

  ASSERT(!m_sqliteTransaction);
  m_sqliteTransaction = WTF::wrapUnique(
      new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly));

  m_database->resetDeletes();
  m_database->disableAuthorizer();
  m_sqliteTransaction->begin();
  m_database->enableAuthorizer();

  // Spec 4.3.2.1+2: Open a transaction to the database, jumping to the error
  // callback if that fails.
  if (!m_sqliteTransaction->inProgress()) {
    ASSERT(!m_database->sqliteDatabase().transactionInProgress());
    m_database->reportStartTransactionResult(
        2, SQLError::kDatabaseErr, m_database->sqliteDatabase().lastError());
    m_transactionError = SQLErrorData::create(
        SQLError::kDatabaseErr, "unable to begin transaction",
        m_database->sqliteDatabase().lastError(),
        m_database->sqliteDatabase().lastErrorMsg());
    m_sqliteTransaction.reset();
    return nextStateForTransactionError();
  }

  // Note: We intentionally retrieve the actual version even with an empty
  // expected version.  In multi-process browsers, we take this opportunity to
  // update the cached value for the actual version. In single-process browsers,
  // this is just a map lookup.
  String actualVersion;
  if (!m_database->getActualVersionForTransaction(actualVersion)) {
    m_database->reportStartTransactionResult(
        3, SQLError::kDatabaseErr, m_database->sqliteDatabase().lastError());
    m_transactionError =
        SQLErrorData::create(SQLError::kDatabaseErr, "unable to read version",
                             m_database->sqliteDatabase().lastError(),
                             m_database->sqliteDatabase().lastErrorMsg());
    m_database->disableAuthorizer();
    m_sqliteTransaction.reset();
    m_database->enableAuthorizer();
    return nextStateForTransactionError();
  }
  m_hasVersionMismatch = !m_database->expectedVersion().isEmpty() &&
                         (m_database->expectedVersion() != actualVersion);

  // Spec 4.3.2.3: Perform preflight steps, jumping to the error callback if
  // they fail.
  if (m_wrapper && !m_wrapper->performPreflight(this)) {
    m_database->disableAuthorizer();
    m_sqliteTransaction.reset();
    m_database->enableAuthorizer();
    if (m_wrapper->sqlError()) {
      m_transactionError = SQLErrorData::create(*m_wrapper->sqlError());
    } else {
      m_database->reportStartTransactionResult(4, SQLError::kUnknownErr, 0);
      m_transactionError = SQLErrorData::create(
          SQLError::kUnknownErr,
          "unknown error occurred during transaction preflight");
    }
    return nextStateForTransactionError();
  }

  // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction
  // object.
  if (m_hasCallback)
    return SQLTransactionState::DeliverTransactionCallback;

  // If we have no callback to make, skip pass to the state after:
  return SQLTransactionState::RunStatements;
}

SQLTransactionState SQLTransactionBackend::runStatements() {
  DCHECK(
      database()->getDatabaseContext()->databaseThread()->isDatabaseThread());
  ASSERT(m_lockAcquired);
  SQLTransactionState nextState;

  // If there is a series of statements queued up that are all successful and
  // have no associated SQLStatementCallback objects, then we can burn through
  // the queue.
  do {
    if (m_shouldRetryCurrentStatement &&
        !m_sqliteTransaction->wasRolledBackBySqlite()) {
      m_shouldRetryCurrentStatement = false;
      // FIXME - Another place that needs fixing up after
      // <rdar://problem/5628468> is addressed.
      // See ::openTransactionAndPreflight() for discussion

      // Reset the maximum size here, as it was increased to allow us to retry
      // this statement.  m_shouldRetryCurrentStatement is set to true only when
      // a statement exceeds the quota, which can happen only in a read-write
      // transaction.  Therefore, there is no need to check here if the
      // transaction is read-write.
      m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());
    } else {
      // If the current statement has already been run, failed due to quota
      // constraints, and we're not retrying it, that means it ended in an
      // error. Handle it now.
      if (m_currentStatementBackend &&
          m_currentStatementBackend->lastExecutionFailedDueToQuota()) {
        return nextStateForCurrentStatementError();
      }

      // Otherwise, advance to the next statement
      getNextStatement();
    }
    nextState = runCurrentStatementAndGetNextState();
  } while (nextState == SQLTransactionState::RunStatements);

  return nextState;
}

void SQLTransactionBackend::getNextStatement() {
  DCHECK(
      database()->getDatabaseContext()->databaseThread()->isDatabaseThread());
  m_currentStatementBackend = nullptr;

  MutexLocker locker(m_statementMutex);
  if (!m_statementQueue.isEmpty())
    m_currentStatementBackend = m_statementQueue.takeFirst();
}

SQLTransactionState
SQLTransactionBackend::runCurrentStatementAndGetNextState() {
  if (!m_currentStatementBackend) {
    // No more statements to run. So move on to the next state.
    return SQLTransactionState::PostflightAndCommit;
  }

  m_database->resetAuthorizer();

  if (m_hasVersionMismatch)
    m_currentStatementBackend->setVersionMismatchedError(m_database.get());

  if (m_currentStatementBackend->execute(m_database.get())) {
    if (m_database->lastActionChangedDatabase()) {
      // Flag this transaction as having changed the database for later delegate
      // notification.
      m_modifiedDatabase = true;
    }

    if (m_currentStatementBackend->hasStatementCallback()) {
      return SQLTransactionState::DeliverStatementCallback;
    }

    // If we get here, then the statement doesn't have a callback to invoke.
    // We can move on to the next statement. Hence, stay in this state.
    return SQLTransactionState::RunStatements;
  }

  if (m_currentStatementBackend->lastExecutionFailedDueToQuota()) {
    return SQLTransactionState::DeliverQuotaIncreaseCallback;
  }

  return nextStateForCurrentStatementError();
}

SQLTransactionState SQLTransactionBackend::nextStateForCurrentStatementError() {
  // Spec 4.3.2.6.6: error - Call the statement's error callback, but if there
  // was no error callback, or the transaction was rolled back, jump to the
  // transaction error callback.
  if (m_currentStatementBackend->hasStatementErrorCallback() &&
      !m_sqliteTransaction->wasRolledBackBySqlite())
    return SQLTransactionState::DeliverStatementCallback;

  if (m_currentStatementBackend->sqlError()) {
    m_transactionError =
        SQLErrorData::create(*m_currentStatementBackend->sqlError());
  } else {
    m_database->reportCommitTransactionResult(1, SQLError::kDatabaseErr, 0);
    m_transactionError = SQLErrorData::create(
        SQLError::kDatabaseErr, "the statement failed to execute");
  }
  return nextStateForTransactionError();
}

SQLTransactionState SQLTransactionBackend::postflightAndCommit() {
  ASSERT(m_lockAcquired);

  // Spec 4.3.2.7: Perform postflight steps, jumping to the error callback if
  // they fail.
  if (m_wrapper && !m_wrapper->performPostflight(this)) {
    if (m_wrapper->sqlError()) {
      m_transactionError = SQLErrorData::create(*m_wrapper->sqlError());
    } else {
      m_database->reportCommitTransactionResult(3, SQLError::kUnknownErr, 0);
      m_transactionError = SQLErrorData::create(
          SQLError::kUnknownErr,
          "unknown error occurred during transaction postflight");
    }
    return nextStateForTransactionError();
  }

  // Spec 4.3.2.7: Commit the transaction, jumping to the error callback if that
  // fails.
  ASSERT(m_sqliteTransaction);

  m_database->disableAuthorizer();
  m_sqliteTransaction->commit();
  m_database->enableAuthorizer();

  // If the commit failed, the transaction will still be marked as "in progress"
  if (m_sqliteTransaction->inProgress()) {
    if (m_wrapper)
      m_wrapper->handleCommitFailedAfterPostflight(this);
    m_database->reportCommitTransactionResult(
        4, SQLError::kDatabaseErr, m_database->sqliteDatabase().lastError());
    m_transactionError = SQLErrorData::create(
        SQLError::kDatabaseErr, "unable to commit transaction",
        m_database->sqliteDatabase().lastError(),
        m_database->sqliteDatabase().lastErrorMsg());
    return nextStateForTransactionError();
  }

  m_database->reportCommitTransactionResult(0, -1, 0);  // OK

  // Vacuum the database if anything was deleted.
  if (m_database->hadDeletes())
    m_database->incrementalVacuumIfNeeded();

  // The commit was successful. If the transaction modified this database,
  // notify the delegates.
  if (m_modifiedDatabase)
    m_database->transactionClient()->didCommitWriteTransaction(database());

  // Spec 4.3.2.8: Deliver success callback, if there is one.
  return SQLTransactionState::DeliverSuccessCallback;
}

SQLTransactionState SQLTransactionBackend::cleanupAndTerminate() {
  ASSERT(m_lockAcquired);

  // Spec 4.3.2.9: End transaction steps. There is no next step.
  STORAGE_DVLOG(1) << "Transaction " << this << " is complete";
  ASSERT(!m_database->sqliteDatabase().transactionInProgress());

  // Phase 5 cleanup. See comment on the SQLTransaction life-cycle above.
  doCleanup();
  m_database->inProgressTransactionCompleted();
  return SQLTransactionState::End;
}

SQLTransactionState SQLTransactionBackend::nextStateForTransactionError() {
  ASSERT(m_transactionError);
  if (m_hasErrorCallback)
    return SQLTransactionState::DeliverTransactionErrorCallback;

  // No error callback, so fast-forward to the next state and rollback the
  // transaction.
  return SQLTransactionState::CleanupAfterTransactionErrorCallback;
}

SQLTransactionState
SQLTransactionBackend::cleanupAfterTransactionErrorCallback() {
  ASSERT(m_lockAcquired);

  STORAGE_DVLOG(1) << "Transaction " << this << " is complete with an error";
  m_database->disableAuthorizer();
  if (m_sqliteTransaction) {
    // Spec 4.3.2.10: Rollback the transaction.
    m_sqliteTransaction->rollback();

    ASSERT(!m_database->sqliteDatabase().transactionInProgress());
    m_sqliteTransaction.reset();
  }
  m_database->enableAuthorizer();

  ASSERT(!m_database->sqliteDatabase().transactionInProgress());

  return SQLTransactionState::CleanupAndTerminate;
}

// requestTransitToState() can be called from the frontend. Hence, it should
// NOT be modifying SQLTransactionBackend in general. The only safe field to
// modify is m_requestedState which is meant for this purpose.
void SQLTransactionBackend::requestTransitToState(
    SQLTransactionState nextState) {
#if DCHECK_IS_ON()
  STORAGE_DVLOG(1) << "Scheduling " << nameForSQLTransactionState(nextState)
                   << " for transaction " << this;
#endif
  m_requestedState = nextState;
  ASSERT(m_requestedState != SQLTransactionState::End);
  m_database->scheduleTransactionStep(this);
}

// This state function is used as a stub function to plug unimplemented states
// in the state dispatch table. They are unimplemented because they should
// never be reached in the course of correct execution.
SQLTransactionState SQLTransactionBackend::unreachableState() {
  ASSERT_NOT_REACHED();
  return SQLTransactionState::End;
}

SQLTransactionState SQLTransactionBackend::sendToFrontendState() {
  ASSERT(m_nextState != SQLTransactionState::Idle);
  m_frontend->requestTransitToState(m_nextState);
  return SQLTransactionState::Idle;
}

}  // namespace blink
