/*
 * Copyright (C) 2006-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. ``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
 * 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 "SQLiteStatement.h"

#include "Logging.h"
#include "SQLValue.h"
#include "SQLiteDatabaseTracker.h"
#include <sqlite3.h>
#include <wtf/Assertions.h>
#include <wtf/Variant.h>
#include <wtf/text/StringView.h>

// SQLite 3.6.16 makes sqlite3_prepare_v2 automatically retry preparing the statement
// once if the database scheme has changed. We rely on this behavior.
#if SQLITE_VERSION_NUMBER < 3006016
#error SQLite version 3.6.16 or newer is required
#endif

namespace WebCore {

SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, sqlite3_stmt* statement)
    : m_database(db)
    , m_statement(statement)
{
    ASSERT(statement);
    m_database.incrementStatementCount();
}

SQLiteStatement::SQLiteStatement(SQLiteStatement&& other)
    : m_database(other.database())
    , m_statement(std::exchange(other.m_statement, nullptr))
{
    m_database.incrementStatementCount();
}

SQLiteStatement::~SQLiteStatement()
{
    sqlite3_finalize(m_statement);
    m_database.decrementStatementCount();
}

int SQLiteStatement::step()
{
    Locker databaseLock { m_database.databaseMutex() };

    // If we're not within a transaction and we call sqlite3_step(), SQLite will implicitly create a transaction for us.
    // In such case, we should bump our transaction count to reflect that.
    std::optional<SQLiteTransactionInProgressAutoCounter> transactionCounter;
    if (!m_database.transactionInProgress() && !isReadOnly())
        transactionCounter.emplace();

    int error = sqlite3_step(m_statement);
    if (error != SQLITE_DONE && error != SQLITE_ROW)
        LOG(SQLDatabase, "sqlite3_step failed (%i)\nError - %s", error, sqlite3_errmsg(m_database.sqlite3Handle()));

    return error;
}

int SQLiteStatement::reset() 
{
    int status = sqlite3_reset(m_statement);
    sqlite3_clear_bindings(m_statement);
    return status;
}

bool SQLiteStatement::executeCommand()
{
    return step() == SQLITE_DONE;
}

int SQLiteStatement::bindBlob(int index, Span<const uint8_t> blob)
{
    ASSERT(index > 0);
    ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    ASSERT(blob.data() || !blob.size());
    ASSERT(blob.size() >= 0);

    return sqlite3_bind_blob(m_statement, index, blob.data(), blob.size(), SQLITE_TRANSIENT);
}

int SQLiteStatement::bindBlob(int index, const String& text)
{
    // String::characters() returns 0 for the empty string, which SQLite
    // treats as a null, so we supply a non-null pointer for that case.
    auto upconvertedCharacters = StringView(text).upconvertedCharacters();
    UChar anyCharacter = 0;
    const UChar* characters;
    if (text.isEmpty() && !text.isNull())
        characters = &anyCharacter;
    else
        characters = upconvertedCharacters;

    return bindBlob(index, Span { reinterpret_cast<const uint8_t*>(characters), text.length() * sizeof(UChar) });
}

int SQLiteStatement::bindText(int index, StringView text)
{
    ASSERT(index > 0);
    ASSERT(static_cast<unsigned>(index) <= bindParameterCount());

    // Fast path when the input text is all ASCII.
    if (text.is8Bit() && text.isAllASCII())
        return sqlite3_bind_text(m_statement, index, text.length() ? reinterpret_cast<const char*>(text.characters8()) : "", text.length(), SQLITE_TRANSIENT);

    auto utf8Text = text.utf8();
    return sqlite3_bind_text(m_statement, index, utf8Text.data(), utf8Text.length(), SQLITE_TRANSIENT);
}

int SQLiteStatement::bindInt(int index, int integer)
{
    ASSERT(index > 0);
    ASSERT(static_cast<unsigned>(index) <= bindParameterCount());

    return sqlite3_bind_int(m_statement, index, integer);
}

int SQLiteStatement::bindInt64(int index, int64_t integer)
{
    ASSERT(index > 0);
    ASSERT(static_cast<unsigned>(index) <= bindParameterCount());

    return sqlite3_bind_int64(m_statement, index, integer);
}

int SQLiteStatement::bindDouble(int index, double number)
{
    ASSERT(index > 0);
    ASSERT(static_cast<unsigned>(index) <= bindParameterCount());

    return sqlite3_bind_double(m_statement, index, number);
}

int SQLiteStatement::bindNull(int index)
{
    ASSERT(index > 0);
    ASSERT(static_cast<unsigned>(index) <= bindParameterCount());

    return sqlite3_bind_null(m_statement, index);
}

int SQLiteStatement::bindValue(int index, const SQLValue& value)
{
    return WTF::switchOn(value,
        [&] (const std::nullptr_t&) { return bindNull(index); },
        [&] (const String& string) { return bindText(index, string); },
        [&] (double number) { return bindDouble(index, number); }
    );
}

unsigned SQLiteStatement::bindParameterCount() const
{
    return sqlite3_bind_parameter_count(m_statement);
}

int SQLiteStatement::columnCount()
{
    return sqlite3_data_count(m_statement);
}

bool SQLiteStatement::isColumnDeclaredAsBlob(int col)
{
    ASSERT(col >= 0);
    return equalLettersIgnoringASCIICase(StringView(sqlite3_column_decltype(m_statement, col)), "blob");
}

String SQLiteStatement::columnName(int col)
{
    ASSERT(col >= 0);
    if (!hasStartedStepping() && step() != SQLITE_ROW)
        return String();
    if (columnCount() <= col)
        return String();
    return String::fromUTF8(sqlite3_column_name(m_statement, col));
}

SQLValue SQLiteStatement::columnValue(int col)
{
    ASSERT(col >= 0);
    if (!hasStartedStepping() && step() != SQLITE_ROW)
        return nullptr;
    if (columnCount() <= col)
        return nullptr;

    // SQLite is typed per value. optional column types are
    // "(mostly) ignored"
    sqlite3_value* value = sqlite3_column_value(m_statement, col);
    switch (sqlite3_value_type(value)) {
    case SQLITE_INTEGER: // SQLValue and JS don't represent integers, so use FLOAT -case
    case SQLITE_FLOAT:
        return sqlite3_value_double(value);
    case SQLITE_BLOB: // SQLValue and JS don't represent blobs, so use TEXT -case
    case SQLITE_TEXT:
        return String::fromUTF8(sqlite3_value_text(value), sqlite3_value_bytes(value));
    case SQLITE_NULL:
        return nullptr;
    default:
        break;
    }

    ASSERT_NOT_REACHED();
    return nullptr;
}

String SQLiteStatement::columnText(int col)
{
    ASSERT(col >= 0);
    if (!hasStartedStepping() && step() != SQLITE_ROW)
        return String();
    if (columnCount() <= col)
        return String();
    return String::fromUTF8(sqlite3_column_text(m_statement, col), sqlite3_column_bytes(m_statement, col));
}
    
double SQLiteStatement::columnDouble(int col)
{
    ASSERT(col >= 0);
    if (!hasStartedStepping() && step() != SQLITE_ROW)
        return 0.0;
    if (columnCount() <= col)
        return 0.0;
    return sqlite3_column_double(m_statement, col);
}

int SQLiteStatement::columnInt(int col)
{
    ASSERT(col >= 0);
    if (!hasStartedStepping() && step() != SQLITE_ROW)
        return 0;
    if (columnCount() <= col)
        return 0;
    return sqlite3_column_int(m_statement, col);
}

int64_t SQLiteStatement::columnInt64(int col)
{
    ASSERT(col >= 0);
    if (!hasStartedStepping() && step() != SQLITE_ROW)
        return 0;
    if (columnCount() <= col)
        return 0;
    return sqlite3_column_int64(m_statement, col);
}

String SQLiteStatement::columnBlobAsString(int col)
{
    ASSERT(col >= 0);

    if (!hasStartedStepping() && step() != SQLITE_ROW)
        return String();

    if (columnCount() <= col)
        return String();

    const void* blob = sqlite3_column_blob(m_statement, col);
    if (!blob)
        return emptyString();

    int size = sqlite3_column_bytes(m_statement, col);
    if (size < 0)
        return String();

    ASSERT(!(size % sizeof(UChar)));
    return String(static_cast<const UChar*>(blob), size / sizeof(UChar));
}

Vector<uint8_t> SQLiteStatement::columnBlob(int col)
{
    auto span = columnBlobAsSpan(col);
    return { span.data(), span.size() };
}

Span<const uint8_t> SQLiteStatement::columnBlobAsSpan(int col)
{
    ASSERT(col >= 0);

    if (!hasStartedStepping() && step() != SQLITE_ROW)
        return { };

    if (columnCount() <= col)
        return { };

    const void* blob = sqlite3_column_blob(m_statement, col);
    if (!blob)
        return { };

    int blobSize = sqlite3_column_bytes(m_statement, col);
    if (blobSize <= 0)
        return { };

    return { static_cast<const uint8_t*>(blob), static_cast<size_t>(blobSize) };
}

bool SQLiteStatement::hasStartedStepping()
{
    return sqlite3_stmt_busy(m_statement);
}

bool SQLiteStatement::isReadOnly()
{
    return sqlite3_stmt_readonly(m_statement);
}

} // namespace WebCore
