/*
 * Copyright (C) 2007, 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/SQLStatementBackend.h"

#include "modules/webdatabase/Database.h"
#include "modules/webdatabase/SQLError.h"
#include "modules/webdatabase/SQLStatement.h"
#include "modules/webdatabase/StorageLog.h"
#include "modules/webdatabase/sqlite/SQLiteDatabase.h"
#include "modules/webdatabase/sqlite/SQLiteStatement.h"
#include "wtf/text/CString.h"

// The Life-Cycle of a SQLStatement i.e. Who's keeping the SQLStatement alive?
// ==========================================================================
// The RefPtr chain goes something like this:
//
//     At birth (in SQLTransactionBackend::executeSQL()):
//     =================================================
//     SQLTransactionBackend
//         // HeapDeque<Member<SQLStatementBackend>> m_statementQueue
//         // points to ...
//     --> SQLStatementBackend
//         // Member<SQLStatement> m_frontend points to ...
//     --> SQLStatement
//
//     After grabbing the statement for execution (in
//     SQLTransactionBackend::getNextStatement()):
//     ======================================================================
//     SQLTransactionBackend
//         // Member<SQLStatementBackend> m_currentStatementBackend
//         // points to ...
//     --> SQLStatementBackend
//         // Member<SQLStatement> m_frontend points to ...
//     --> SQLStatement
//
//     Then we execute the statement in
//     SQLTransactionBackend::runCurrentStatementAndGetNextState().
//     And we callback to the script in
//     SQLTransaction::deliverStatementCallback() if necessary.
//     - Inside SQLTransaction::deliverStatementCallback(), we operate on a raw
//       SQLStatement*.  This pointer is valid because it is owned by
//       SQLTransactionBackend's
//       SQLTransactionBackend::m_currentStatementBackend.
//
//     After we're done executing the statement (in
//     SQLTransactionBackend::getNextStatement()):
//     ======================================================================
//     When we're done executing, we'll grab the next statement. But before we
//     do that, getNextStatement() nullify
//     SQLTransactionBackend::m_currentStatementBackend.
//     This will trigger the deletion of the SQLStatementBackend and
//     SQLStatement.
//
//     Note: unlike with SQLTransaction, there is no JS representation of
//     SQLStatement.  Hence, there is no GC dependency at play here.

namespace blink {

SQLStatementBackend* SQLStatementBackend::create(
    SQLStatement* frontend,
    const String& statement,
    const Vector<SQLValue>& arguments,
    int permissions) {
  return new SQLStatementBackend(frontend, statement, arguments, permissions);
}

SQLStatementBackend::SQLStatementBackend(SQLStatement* frontend,
                                         const String& statement,
                                         const Vector<SQLValue>& arguments,
                                         int permissions)
    : m_frontend(frontend),
      m_statement(statement.isolatedCopy()),
      m_arguments(arguments),
      m_hasCallback(m_frontend->hasCallback()),
      m_hasErrorCallback(m_frontend->hasErrorCallback()),
      m_resultSet(SQLResultSet::create()),
      m_permissions(permissions) {
  DCHECK(isMainThread());

  m_frontend->setBackend(this);
}

DEFINE_TRACE(SQLStatementBackend) {
  visitor->trace(m_frontend);
  visitor->trace(m_resultSet);
}

SQLStatement* SQLStatementBackend::frontend() {
  return m_frontend.get();
}

SQLErrorData* SQLStatementBackend::sqlError() const {
  return m_error.get();
}

SQLResultSet* SQLStatementBackend::sqlResultSet() const {
  return m_resultSet->isValid() ? m_resultSet.get() : 0;
}

bool SQLStatementBackend::execute(Database* db) {
  ASSERT(!m_resultSet->isValid());

  // If we're re-running this statement after a quota violation, we need to
  // clear that error now
  clearFailureDueToQuota();

  // This transaction might have been marked bad while it was being set up on
  // the main thread, so if there is still an error, return false.
  if (m_error)
    return false;

  db->setAuthorizerPermissions(m_permissions);

  SQLiteDatabase* database = &db->sqliteDatabase();

  SQLiteStatement statement(*database, m_statement);
  int result = statement.prepare();

  if (result != SQLResultOk) {
    STORAGE_DVLOG(1) << "Unable to verify correctness of statement "
                     << m_statement << " - error " << result << " ("
                     << database->lastErrorMsg() << ")";
    if (result == SQLResultInterrupt)
      m_error = SQLErrorData::create(SQLError::kDatabaseErr,
                                     "could not prepare statement", result,
                                     "interrupted");
    else
      m_error = SQLErrorData::create(SQLError::kSyntaxErr,
                                     "could not prepare statement", result,
                                     database->lastErrorMsg());
    db->reportExecuteStatementResult(1, m_error->code(), result);
    return false;
  }

  // FIXME: If the statement uses the ?### syntax supported by sqlite, the bind
  // parameter count is very likely off from the number of question marks.  If
  // this is the case, they might be trying to do something fishy or malicious
  if (statement.bindParameterCount() != m_arguments.size()) {
    STORAGE_DVLOG(1)
        << "Bind parameter count doesn't match number of question marks";
    m_error = SQLErrorData::create(
        SQLError::kSyntaxErr,
        "number of '?'s in statement string does not match argument count");
    db->reportExecuteStatementResult(2, m_error->code(), 0);
    return false;
  }

  for (unsigned i = 0; i < m_arguments.size(); ++i) {
    result = statement.bindValue(i + 1, m_arguments[i]);
    if (result == SQLResultFull) {
      setFailureDueToQuota(db);
      return false;
    }

    if (result != SQLResultOk) {
      STORAGE_DVLOG(1) << "Failed to bind value index " << (i + 1)
                       << " to statement for query " << m_statement;
      db->reportExecuteStatementResult(3, SQLError::kDatabaseErr, result);
      m_error =
          SQLErrorData::create(SQLError::kDatabaseErr, "could not bind value",
                               result, database->lastErrorMsg());
      return false;
    }
  }

  // Step so we can fetch the column names.
  result = statement.step();
  if (result == SQLResultRow) {
    int columnCount = statement.columnCount();
    SQLResultSetRowList* rows = m_resultSet->rows();

    for (int i = 0; i < columnCount; i++)
      rows->addColumn(statement.getColumnName(i));

    do {
      for (int i = 0; i < columnCount; i++)
        rows->addResult(statement.getColumnValue(i));

      result = statement.step();
    } while (result == SQLResultRow);

    if (result != SQLResultDone) {
      db->reportExecuteStatementResult(4, SQLError::kDatabaseErr, result);
      m_error = SQLErrorData::create(SQLError::kDatabaseErr,
                                     "could not iterate results", result,
                                     database->lastErrorMsg());
      return false;
    }
  } else if (result == SQLResultDone) {
    // Didn't find anything, or was an insert
    if (db->lastActionWasInsert())
      m_resultSet->setInsertId(database->lastInsertRowID());
  } else if (result == SQLResultFull) {
    // Return the Quota error - the delegate will be asked for more space and
    // this statement might be re-run.
    setFailureDueToQuota(db);
    return false;
  } else if (result == SQLResultConstraint) {
    db->reportExecuteStatementResult(6, SQLError::kConstraintErr, result);
    m_error = SQLErrorData::create(
        SQLError::kConstraintErr,
        "could not execute statement due to a constaint failure", result,
        database->lastErrorMsg());
    return false;
  } else {
    db->reportExecuteStatementResult(5, SQLError::kDatabaseErr, result);
    m_error = SQLErrorData::create(SQLError::kDatabaseErr,
                                   "could not execute statement", result,
                                   database->lastErrorMsg());
    return false;
  }

  // FIXME: If the spec allows triggers, and we want to be "accurate" in a
  // different way, we'd use sqlite3_total_changes() here instead of
  // sqlite3_changed, because that includes rows modified from within a trigger.
  // For now, this seems sufficient.
  m_resultSet->setRowsAffected(database->lastChanges());

  db->reportExecuteStatementResult(0, -1, 0);  // OK
  return true;
}

void SQLStatementBackend::setVersionMismatchedError(Database* database) {
  ASSERT(!m_error && !m_resultSet->isValid());
  database->reportExecuteStatementResult(7, SQLError::kVersionErr, 0);
  m_error = SQLErrorData::create(
      SQLError::kVersionErr,
      "current version of the database and `oldVersion` argument do not match");
}

void SQLStatementBackend::setFailureDueToQuota(Database* database) {
  ASSERT(!m_error && !m_resultSet->isValid());
  database->reportExecuteStatementResult(8, SQLError::kQuotaErr, 0);
  m_error = SQLErrorData::create(SQLError::kQuotaErr,
                                 "there was not enough remaining storage "
                                 "space, or the storage quota was reached and "
                                 "the user declined to allow more space");
}

void SQLStatementBackend::clearFailureDueToQuota() {
  if (lastExecutionFailedDueToQuota())
    m_error = nullptr;
}

bool SQLStatementBackend::lastExecutionFailedDueToQuota() const {
  return m_error && m_error->code() == SQLError::kQuotaErr;
}

}  // namespace blink
