/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "SQLiteRawStatement"

#include <string.h>
#include <algorithm>

#include <jni.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/scoped_primitive_array.h>
#include <nativehelper/scoped_string_chars.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
#include <android-base/stringprintf.h>
#include <core_jni_helpers.h>

#include <utils/Log.h>
#include <utils/Unicode.h>

#include <sqlite3.h>
#include <sqlite3_android.h>

#include "android_database_SQLiteCommon.h"

/**
 * JNI functions supporting the android.database.sqlite.SQLiteRawStatement class.
 */
namespace android {

// Helper functions.
static sqlite3 *db(long statementPtr) {
    return sqlite3_db_handle(reinterpret_cast<sqlite3_stmt*>(statementPtr));
}

static sqlite3_stmt* stmt(long statementPtr) {
    return reinterpret_cast<sqlite3_stmt*>(statementPtr);
}

// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the parameter index is out
// of bounds.  The function exists to construct an error message that includes
// the bounds.
static void throwInvalidParameter(JNIEnv *env, jlong stmtPtr, jint index) {
    if (sqlite3_extended_errcode(db(stmtPtr)) == SQLITE_RANGE) {
        int count = sqlite3_bind_parameter_count(stmt(stmtPtr));
        std::string message = android::base::StringPrintf(
            "parameter index %d out of bounds [1,%d]", index, count);
        char const * errmsg = sqlite3_errstr(SQLITE_RANGE);
        throw_sqlite3_exception(env, SQLITE_RANGE, errmsg, message.c_str());
    } else {
        throw_sqlite3_exception(env, db(stmtPtr), nullptr);
    }
}


// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is out
// of bounds.
static void throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) {
    if (col < 0 || col >= sqlite3_data_count(stmt(stmtPtr))) {
        int count = sqlite3_data_count(stmt(stmtPtr));
        std::string message = android::base::StringPrintf(
            "column index %d out of bounds [0,%d]", col, count - 1);
        char const * errmsg = sqlite3_errstr(SQLITE_RANGE);
        throw_sqlite3_exception(env, SQLITE_RANGE, errmsg, message.c_str());
    }
}


static jint bindParameterCount(JNIEnv* env, jclass, jlong stmtPtr) {
    return sqlite3_bind_parameter_count(stmt(stmtPtr));
}

// jname must be in standard UTF-8.  This throws an NPE if jname is null.
static jint bindParameterIndex(JNIEnv *env, jclass, jlong stmtPtr, jstring jname) {
    ScopedStringChars name(env, jname);
    if (name.get() == nullptr) {
        return 0;
    }
    size_t len16 = env->GetStringLength(jname);
    size_t len8 = utf16_to_utf8_length(reinterpret_cast<const char16_t*>(name.get()), len16);
    // The extra byte is for the terminating null.
    char *utf8Name = new char[len8 + 1];
    utf16_to_utf8(reinterpret_cast<const char16_t*>(name.get()), len16, utf8Name, len8 + 1);
    int r = sqlite3_bind_parameter_index(stmt(stmtPtr), utf8Name);
    delete [] utf8Name;
    return r;
}

// The name returned from the database is UTF-8.  If there is no matching name,
// null is returned.
static jstring bindParameterName(JNIEnv *env, jclass, jlong stmtPtr, jint param) {
    char const *src = sqlite3_bind_parameter_name(stmt(stmtPtr), param);
    if (src == nullptr) {
        return NULL;
    }
    return env->NewStringUTF(src);
}

static jint columnCount(JNIEnv* env, jclass, jlong stmtPtr) {
    return sqlite3_column_count(stmt(stmtPtr));
}

// Step the prepared statement.  If the result is other than ROW, DONE, BUSY, or LOCKED, throw an
// exception if throwOnError is true.  The advantage of throwing from the native latyer is that
// all the error codes and error strings are easily visible.
static jint step(JNIEnv* env, jclass, jlong stmtPtr, jboolean throwOnError) {
    sqlite3_stmt* statement = stmt(stmtPtr);
    int err = sqlite3_step(statement);
    switch (err) {
        case SQLITE_ROW:
        case SQLITE_DONE:
        case SQLITE_BUSY:
        case SQLITE_LOCKED:
            return err;
    }
    if (throwOnError) {
        throw_sqlite3_exception(env, db(stmtPtr), "failure in step()");
    }
    return err;
}

static void reset(JNIEnv*, jclass, jlong stmtPtr, jboolean clear) {
    if (clear) sqlite3_clear_bindings(stmt(stmtPtr));
    // The return value is ignored.
    sqlite3_reset(stmt(stmtPtr));
}

static void clearBindings(JNIEnv*, jclass, jlong stmtPtr) {
    sqlite3_clear_bindings(stmt(stmtPtr));
}


// This binds null to the parameter if the incoming array is null.
static void bindBlob(JNIEnv* env, jclass obj, jlong stmtPtr, jint index, jbyteArray val,
        jint offset, jint length) {
    ScopedByteArrayRO value(env, val);
    int err;
    if (value.get() == nullptr) {
        err = sqlite3_bind_null(stmt(stmtPtr), index);
    } else {
        err = sqlite3_bind_blob(stmt(stmtPtr), index, value.get() + offset,
                                length, SQLITE_TRANSIENT);
    }
    if (err != SQLITE_OK) {
        throwInvalidParameter(env, stmtPtr, index);
    }
}

static void bindDouble(JNIEnv* env, jclass, jlong stmtPtr, jint index, jdouble val) {
    if (sqlite3_bind_double(stmt(stmtPtr), index, val) != SQLITE_OK) {
        throwInvalidParameter(env, stmtPtr, index);
    }
}

static void bindInt(JNIEnv* env, jclass, jlong stmtPtr, jint index, jint val) {
    if (sqlite3_bind_int(stmt(stmtPtr), index, val) != SQLITE_OK) {
        throwInvalidParameter(env, stmtPtr, index);
    }
}

static void bindLong(JNIEnv* env, jclass, jlong stmtPtr, jint index, jlong val) {
    if (sqlite3_bind_int64(stmt(stmtPtr), index, val) != SQLITE_OK) {
        throwInvalidParameter(env, stmtPtr, index);
    }
}

static void bindNull(JNIEnv* env, jclass, jlong stmtPtr, jint index) {
    if (sqlite3_bind_null(stmt(stmtPtr), index) != SQLITE_OK) {
        throwInvalidParameter(env, stmtPtr, index);
    }
}

// This binds null to the parameter if the string is null.
static void bindText(JNIEnv* env, jclass, jlong stmtPtr, jint index, jstring val) {
    ScopedStringChars value(env, val);
    int err;
    if (value.get() == nullptr) {
        err = sqlite3_bind_null(stmt(stmtPtr), index);
    } else {
        jsize valueLength = env->GetStringLength(val);
        err = sqlite3_bind_text16(stmt(stmtPtr), index, value.get(),
            valueLength * sizeof(jchar), SQLITE_TRANSIENT);
    }
    if (err != SQLITE_OK) {
        throwInvalidParameter(env, stmtPtr, index);
    }
}


static jint columnType(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    throwIfInvalidColumn(env, stmtPtr, col);
    return sqlite3_column_type(stmt(stmtPtr), col);
}

static jstring columnName(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    throwIfInvalidColumn(env, stmtPtr, col);
    const jchar* name = static_cast<const jchar*>(sqlite3_column_name16(stmt(stmtPtr), col));
    if (name == nullptr) {
        throw_sqlite3_exception(env, db(stmtPtr), "error fetching columnName()");
        return NULL;
    }
    size_t length = strlen16(reinterpret_cast<const char16_t*>(name));
    return env->NewString(name, length);
}

static jint columnBytes(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    throwIfInvalidColumn(env, stmtPtr, col);
    return sqlite3_column_bytes16(stmt(stmtPtr), col);
}


static jbyteArray columnBlob(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    throwIfInvalidColumn(env, stmtPtr, col);
    const void* blob = sqlite3_column_blob(stmt(stmtPtr), col);
    if (blob == nullptr) {
        return NULL;
    }
    size_t size = sqlite3_column_bytes(stmt(stmtPtr), col);
    jbyteArray result = env->NewByteArray(size);
    if (result == nullptr) {
        // An OutOfMemory exception will have been thrown.
        return NULL;
    }
    env->SetByteArrayRegion(result, 0, size, reinterpret_cast<const jbyte*>(blob));
    return result;
}

static int columnBuffer(JNIEnv* env, jclass, jlong stmtPtr, jint col,
        jbyteArray buffer, jint offset, jint length, jint srcOffset) {
    throwIfInvalidColumn(env, stmtPtr, col);
    const void* blob = sqlite3_column_blob(stmt(stmtPtr), col);
    if (blob == nullptr) {
        return 0;
    }
    jsize bsize = sqlite3_column_bytes(stmt(stmtPtr), col);
    if (bsize == 0 || bsize <= srcOffset) {
        return 0;
    }
    jsize want = std::min(bsize - srcOffset, length);
    env->SetByteArrayRegion(buffer, offset, want, reinterpret_cast<const jbyte*>(blob) + srcOffset);
    return want;
}

static jdouble columnDouble(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    throwIfInvalidColumn(env, stmtPtr, col);
    return sqlite3_column_double(stmt(stmtPtr), col);
}

static jint columnInt(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    throwIfInvalidColumn(env, stmtPtr, col);
    return sqlite3_column_int(stmt(stmtPtr), col);
}

static jlong columnLong(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    throwIfInvalidColumn(env, stmtPtr, col);
    return sqlite3_column_int64(stmt(stmtPtr), col);
}

static jstring columnText(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    throwIfInvalidColumn(env, stmtPtr, col);
    const jchar* text = static_cast<const jchar*>(sqlite3_column_text16(stmt(stmtPtr), col));
    if (text == nullptr) {
        return NULL;
    }
    size_t length = sqlite3_column_bytes16(stmt(stmtPtr), col) / sizeof(jchar);
    return env->NewString(text, length);
}

static const JNINativeMethod sStatementMethods[] =
{
    // Metadata
    { "nativeBindParameterCount", "(J)I", (void*) bindParameterCount },
    { "nativeBindParameterIndex", "(JLjava/lang/String;)I", (void*) bindParameterIndex },
    { "nativeBindParameterName", "(JI)Ljava/lang/String;", (void*) bindParameterName },

    // Operations on a statement
    { "nativeStep", "(JZ)I", (void*) step },
    { "nativeReset", "(JZ)V", (void*) reset },
    { "nativeClearBindings", "(J)V", (void*) clearBindings },

    // Methods that bind values to parameters
    { "nativeBindBlob", "(JI[BII)V", (void*) bindBlob },
    { "nativeBindDouble", "(JID)V", (void*) bindDouble },
    { "nativeBindInt", "(JII)V", (void*) bindInt },
    { "nativeBindLong", "(JIJ)V", (void*) bindLong },
    { "nativeBindNull", "(JI)V", (void*) bindNull },
    { "nativeBindText", "(JILjava/lang/String;)V", (void*) bindText },

    // Methods that return information about columns in a result row.
    { "nativeColumnCount", "(J)I", (void*) columnCount },
    { "nativeColumnType", "(JI)I", (void*) columnType },
    { "nativeColumnName", "(JI)Ljava/lang/String;", (void*) columnName },

    { "nativeColumnBytes", "(JI)I", (void*) columnBytes },

    { "nativeColumnBlob", "(JI)[B", (void*) columnBlob },
    { "nativeColumnBuffer", "(JI[BIII)I", (void*) columnBuffer },
    { "nativeColumnDouble", "(JI)D", (void*) columnDouble },
    { "nativeColumnInt", "(JI)I", (void*) columnInt },
    { "nativeColumnLong", "(JI)J", (void*) columnLong },
    { "nativeColumnText", "(JI)Ljava/lang/String;", (void*) columnText },
};

int register_android_database_SQLiteRawStatement(JNIEnv *env)
{
    return RegisterMethodsOrDie(env, "android/database/sqlite/SQLiteRawStatement",
                                sStatementMethods, NELEM(sStatementMethods));
}

} // namespace android
