/*
 * 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 "platform/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)
    : frontend_(frontend),
      statement_(statement.IsolatedCopy()),
      arguments_(arguments),
      has_callback_(frontend_->HasCallback()),
      has_error_callback_(frontend_->HasErrorCallback()),
      result_set_(SQLResultSet::Create()),
      permissions_(permissions) {
  DCHECK(IsMainThread());

  frontend_->SetBackend(this);
}

DEFINE_TRACE(SQLStatementBackend) {
  visitor->Trace(frontend_);
  visitor->Trace(result_set_);
}

SQLStatement* SQLStatementBackend::GetFrontend() {
  return frontend_.Get();
}

SQLErrorData* SQLStatementBackend::SqlError() const {
  return error_.get();
}

SQLResultSet* SQLStatementBackend::SqlResultSet() const {
  return result_set_->IsValid() ? result_set_.Get() : 0;
}

bool SQLStatementBackend::Execute(Database* db) {
  DCHECK(!result_set_->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 (error_)
    return false;

  db->SetAuthorizerPermissions(permissions_);

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

  SQLiteStatement statement(*database, statement_);
  int result = statement.Prepare();

  if (result != kSQLResultOk) {
    STORAGE_DVLOG(1) << "Unable to verify correctness of statement "
                     << statement_ << " - error " << result << " ("
                     << database->LastErrorMsg() << ")";
    if (result == kSQLResultInterrupt)
      error_ = SQLErrorData::Create(SQLError::kDatabaseErr,
                                    "could not prepare statement", result,
                                    "interrupted");
    else
      error_ = SQLErrorData::Create(SQLError::kSyntaxErr,
                                    "could not prepare statement", result,
                                    database->LastErrorMsg());
    db->ReportExecuteStatementResult(1, 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() != arguments_.size()) {
    STORAGE_DVLOG(1)
        << "Bind parameter count doesn't match number of question marks";
    error_ = SQLErrorData::Create(
        SQLError::kSyntaxErr,
        "number of '?'s in statement string does not match argument count");
    db->ReportExecuteStatementResult(2, error_->Code(), 0);
    return false;
  }

  for (unsigned i = 0; i < arguments_.size(); ++i) {
    result = statement.BindValue(i + 1, arguments_[i]);
    if (result == kSQLResultFull) {
      SetFailureDueToQuota(db);
      return false;
    }

    if (result != kSQLResultOk) {
      STORAGE_DVLOG(1) << "Failed to bind value index " << (i + 1)
                       << " to statement for query " << statement_;
      db->ReportExecuteStatementResult(3, SQLError::kDatabaseErr, result);
      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 == kSQLResultRow) {
    int column_count = statement.ColumnCount();
    SQLResultSetRowList* rows = result_set_->rows();

    for (int i = 0; i < column_count; i++)
      rows->AddColumn(statement.GetColumnName(i));

    do {
      for (int i = 0; i < column_count; i++)
        rows->AddResult(statement.GetColumnValue(i));

      result = statement.Step();
    } while (result == kSQLResultRow);

    if (result != kSQLResultDone) {
      db->ReportExecuteStatementResult(4, SQLError::kDatabaseErr, result);
      error_ = SQLErrorData::Create(SQLError::kDatabaseErr,
                                    "could not iterate results", result,
                                    database->LastErrorMsg());
      return false;
    }
  } else if (result == kSQLResultDone) {
    // Didn't find anything, or was an insert
    if (db->LastActionWasInsert())
      result_set_->SetInsertId(database->LastInsertRowID());
  } else if (result == kSQLResultFull) {
    // 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 == kSQLResultConstraint) {
    db->ReportExecuteStatementResult(6, SQLError::kConstraintErr, result);
    error_ = SQLErrorData::Create(
        SQLError::kConstraintErr,
        "could not execute statement due to a constraint failure", result,
        database->LastErrorMsg());
    return false;
  } else {
    db->ReportExecuteStatementResult(5, SQLError::kDatabaseErr, result);
    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.
  result_set_->SetRowsAffected(database->LastChanges());

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

void SQLStatementBackend::SetVersionMismatchedError(Database* database) {
  DCHECK(!error_);
  DCHECK(!result_set_->IsValid());
  database->ReportExecuteStatementResult(7, SQLError::kVersionErr, 0);
  error_ = SQLErrorData::Create(
      SQLError::kVersionErr,
      "current version of the database and `oldVersion` argument do not match");
}

void SQLStatementBackend::SetFailureDueToQuota(Database* database) {
  DCHECK(!error_);
  DCHECK(!result_set_->IsValid());
  database->ReportExecuteStatementResult(8, SQLError::kQuotaErr, 0);
  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())
    error_ = nullptr;
}

bool SQLStatementBackend::LastExecutionFailedDueToQuota() const {
  return error_ && error_->Code() == SQLError::kQuotaErr;
}

}  // namespace blink
