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

#undef LOG_TAG
#define LOG_TAG "CursorWindow"

#include <jni.h>
#include <JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>

#include <utils/Log.h>
#include <utils/String8.h>
#include <utils/String16.h>

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "CursorWindow.h"
#include "sqlite3_exception.h"
#include "android_util_Binder.h"


namespace android {

static jfieldID gWindowField;
static jfieldID gBufferField;
static jfieldID gSizeCopiedField;

#define GET_WINDOW(env, object) ((CursorWindow *)env->GetIntField(object, gWindowField))
#define SET_WINDOW(env, object, window) (env->SetIntField(object, gWindowField, (int)window))
#define SET_BUFFER(env, object, buf) (env->SetObjectField(object, gBufferField, buf))
#define SET_SIZE_COPIED(env, object, size) (env->SetIntField(object, gSizeCopiedField, size))

CursorWindow * get_window_from_object(JNIEnv * env, jobject javaWindow)
{
    return GET_WINDOW(env, javaWindow);
}

static void native_init_empty(JNIEnv * env, jobject object, jboolean localOnly)
{
    uint8_t * data;
    size_t size;
    CursorWindow * window;

    window = new CursorWindow(MAX_WINDOW_SIZE);
    if (!window) {
        jniThrowException(env, "java/lang/RuntimeException", "No memory for native window object");
        return;
    }

    if (!window->initBuffer(localOnly)) {
        jniThrowException(env, "java/lang/IllegalStateException", "Couldn't init cursor window");
        delete window;
        return;
    }

LOG_WINDOW("native_init_empty: window = %p", window);
    SET_WINDOW(env, object, window);
}

static void native_init_memory(JNIEnv * env, jobject object, jobject memObj)
{
    sp<IMemory> memory = interface_cast<IMemory>(ibinderForJavaObject(env, memObj));
    if (memory == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Couldn't get native binder");
        return;
    }

    CursorWindow * window = new CursorWindow();
    if (!window) {
        jniThrowException(env, "java/lang/RuntimeException", "No memory for native window object");
        return;
    }
    if (!window->setMemory(memory)) {
        jniThrowException(env, "java/lang/RuntimeException", "No memory in memObj");
        delete window;
        return;
    }

LOG_WINDOW("native_init_memory: numRows = %d, numColumns = %d, window = %p", window->getNumRows(), window->getNumColumns(), window);
    SET_WINDOW(env, object, window);
}

static jobject native_getBinder(JNIEnv * env, jobject object)
{
    CursorWindow * window = GET_WINDOW(env, object);
    if (window) {
        sp<IMemory> memory = window->getMemory();
        if (memory != NULL) {
            sp<IBinder> binder = memory->asBinder();
            return javaObjectForIBinder(env, binder);
        }
    }
    return NULL;
}

static void native_clear(JNIEnv * env, jobject object)
{
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Clearing window %p", window);
    if (window == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "clear() called after close()");
        return;
    }
    window->clear();
}

static void native_close(JNIEnv * env, jobject object)
{
    CursorWindow * window = GET_WINDOW(env, object);
    if (window) {
LOG_WINDOW("Closing window %p", window);
        delete window;
        SET_WINDOW(env, object, 0);
    }
}

static void throwExceptionWithRowCol(JNIEnv * env, jint row, jint column)
{
    char buf[100];
    snprintf(buf, sizeof(buf), "get field slot from row %d col %d failed", row, column);
    jniThrowException(env, "java/lang/IllegalStateException", buf);
}

static void throwUnknowTypeException(JNIEnv * env, jint type)
{
    char buf[80];
    snprintf(buf, sizeof(buf), "UNKNOWN type %d", type);
    jniThrowException(env, "java/lang/IllegalStateException", buf);
}

static jlong getLong_native(JNIEnv * env, jobject object, jint row, jint column)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Getting long for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        throwExceptionWithRowCol(env, row, column);
        return 0;
    }

    uint8_t type = field.type;
    if (type == FIELD_TYPE_INTEGER) {
        int64_t value;
        if (window->getLong(row, column, &value)) {
            return value;
        }
        return 0;
    } else if (type == FIELD_TYPE_STRING) {
        uint32_t size = field.data.buffer.size;
        if (size > 0) {
#if WINDOW_STORAGE_UTF8
            return strtoll((char const *)window->offsetToPtr(field.data.buffer.offset), NULL, 0);
#else
            String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
            char const * str = ascii.string();
            return strtoll(str, NULL, 0);
#endif
        } else {
            return 0;
        }
    } else if (type == FIELD_TYPE_FLOAT) {
        double value;
        if (window->getDouble(row, column, &value)) {
            return value;
        }
        return 0;
    } else if (type == FIELD_TYPE_NULL) {
        return 0;
    } else if (type == FIELD_TYPE_BLOB) {
        throw_sqlite3_exception(env, "Unable to convert BLOB to long");
        return 0;
    } else {
        throwUnknowTypeException(env, type);
        return 0;
    }
}

static jbyteArray getBlob_native(JNIEnv* env, jobject object, jint row, jint column)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Getting blob for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        throwExceptionWithRowCol(env, row, column);
        return NULL;
    }

    uint8_t type = field.type;
    if (type == FIELD_TYPE_BLOB || type == FIELD_TYPE_STRING) {
        jbyteArray byteArray = env->NewByteArray(field.data.buffer.size);
        LOG_ASSERT(byteArray, "Native could not create new byte[]");
        env->SetByteArrayRegion(byteArray, 0, field.data.buffer.size,
            (const jbyte*)window->offsetToPtr(field.data.buffer.offset));
        return byteArray;
    } else if (type == FIELD_TYPE_INTEGER) {
        throw_sqlite3_exception(env, "INTEGER data in getBlob_native ");
    } else if (type == FIELD_TYPE_FLOAT) {
        throw_sqlite3_exception(env, "FLOAT data in getBlob_native ");
    } else if (type == FIELD_TYPE_NULL) {
        // do nothing
    } else {
        throwUnknowTypeException(env, type);
    }
    return NULL;
}

static jboolean isBlob_native(JNIEnv* env, jobject object, jint row, jint column)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Checking if column is a blob or null for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        throwExceptionWithRowCol(env, row, column);
        return NULL;
    }

    return field.type == FIELD_TYPE_BLOB || field.type == FIELD_TYPE_NULL;
}

static jboolean isString_native(JNIEnv* env, jobject object, jint row, jint column)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Checking if column is a string or null for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        throwExceptionWithRowCol(env, row, column);
        return NULL;
    }

    return field.type == FIELD_TYPE_STRING || field.type == FIELD_TYPE_NULL;
}

static jboolean isInteger_native(JNIEnv* env, jobject object, jint row, jint column)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Checking if column is an integer for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        throwExceptionWithRowCol(env, row, column);
        return NULL;
    }

    return field.type == FIELD_TYPE_INTEGER;
}

static jboolean isFloat_native(JNIEnv* env, jobject object, jint row, jint column)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Checking if column is a float for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        throwExceptionWithRowCol(env, row, column);
        return NULL;
    }

    return field.type == FIELD_TYPE_FLOAT;
}

static jstring getString_native(JNIEnv* env, jobject object, jint row, jint column)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Getting string for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        throwExceptionWithRowCol(env, row, column);
        return NULL;
    }

    uint8_t type = field.type;
    if (type == FIELD_TYPE_STRING) {
        uint32_t size = field.data.buffer.size;
        if (size > 0) {
#if WINDOW_STORAGE_UTF8
            // Pass size - 1 since the UTF8 is null terminated and we don't want a null terminator on the UTF16 string
            String16 utf16((char const *)window->offsetToPtr(field.data.buffer.offset), size - 1);
            return env->NewString((jchar const *)utf16.string(), utf16.size());
#else
            return env->NewString((jchar const *)window->offsetToPtr(field.data.buffer.offset), size / 2);
#endif
        } else {
            return env->NewStringUTF("");
        }
    } else if (type == FIELD_TYPE_INTEGER) {
        int64_t value;
        if (window->getLong(row, column, &value)) {
            char buf[32];
            snprintf(buf, sizeof(buf), "%lld", value);
            return env->NewStringUTF(buf);
        }
        return NULL;
    } else if (type == FIELD_TYPE_FLOAT) {
        double value;
        if (window->getDouble(row, column, &value)) {
            char buf[32];
            snprintf(buf, sizeof(buf), "%g", value);
            return env->NewStringUTF(buf);
        }
        return NULL;
    } else if (type == FIELD_TYPE_NULL) {
        return NULL;
    } else if (type == FIELD_TYPE_BLOB) {
        throw_sqlite3_exception(env, "Unable to convert BLOB to string");
        return NULL;
    } else {
        throwUnknowTypeException(env, type);
        return NULL;
    }
}

/**
 * Use this only to convert characters that are known to be within the
 * 0-127 range for direct conversion to UTF-16
 */
static jint charToJchar(const char* src, jchar* dst, jint bufferSize)
{
    int32_t len = strlen(src);

    if (bufferSize < len) {
        len = bufferSize;
    }

    for (int i = 0; i < len; i++) {
        *dst++ = (*src++ & 0x7F);
    }
    return len;
}

static jcharArray copyStringToBuffer_native(JNIEnv* env, jobject object, jint row,
                                      jint column, jint bufferSize, jobject buf)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Copying string for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        jniThrowException(env, "java/lang/IllegalStateException", "Unable to get field slot");
        return NULL;
    }

    jcharArray buffer = (jcharArray)env->GetObjectField(buf, gBufferField);
    if (buffer == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "buf should not be null");
        return NULL;
    }
    jchar* dst = env->GetCharArrayElements(buffer, NULL);
    uint8_t type = field.type;
    uint32_t sizeCopied = 0;
    jcharArray newArray = NULL;
    if (type == FIELD_TYPE_STRING) {
        uint32_t size = field.data.buffer.size;
        if (size > 0) {
#if WINDOW_STORAGE_UTF8
            // Pass size - 1 since the UTF8 is null terminated and we don't want a null terminator on the UTF16 string
            String16 utf16((char const *)window->offsetToPtr(field.data.buffer.offset), size - 1);
            int32_t strSize = utf16.size();
            if (strSize > bufferSize || dst == NULL) {
                newArray = env->NewCharArray(strSize);
                env->SetCharArrayRegion(newArray, 0, strSize, (jchar const *)utf16.string());
            } else {
                memcpy(dst, (jchar const *)utf16.string(), strSize * 2);
            }
            sizeCopied = strSize;
#else
            sizeCopied = size/2 + size % 2;
            if (size > bufferSize * 2 || dst == NULL) {
                newArray = env->NewCharArray(sizeCopied);
                memcpy(newArray, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
            } else {
                memcpy(dst, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
            }
#endif
        }
    } else if (type == FIELD_TYPE_INTEGER) {
        int64_t value;
        if (window->getLong(row, column, &value)) {
            char buf[32];
            int len;
            snprintf(buf, sizeof(buf), "%lld", value);
            jchar* dst = env->GetCharArrayElements(buffer, NULL);
            sizeCopied = charToJchar(buf, dst, bufferSize);
         }
    } else if (type == FIELD_TYPE_FLOAT) {
        double value;
        if (window->getDouble(row, column, &value)) {
            char tempbuf[32];
            snprintf(tempbuf, sizeof(tempbuf), "%g", value);
            jchar* dst = env->GetCharArrayElements(buffer, NULL);
            sizeCopied = charToJchar(tempbuf, dst, bufferSize);
        }
    } else if (type == FIELD_TYPE_NULL) {
    } else if (type == FIELD_TYPE_BLOB) {
        throw_sqlite3_exception(env, "Unable to convert BLOB to string");
    } else {
        LOGE("Unknown field type %d", type);
        throw_sqlite3_exception(env, "UNKNOWN type in copyStringToBuffer_native()");
    }
    SET_SIZE_COPIED(env, buf, sizeCopied);
    env->ReleaseCharArrayElements(buffer, dst, JNI_OK);
    return newArray;
}

static jdouble getDouble_native(JNIEnv* env, jobject object, jint row, jint column)
{
    int32_t err;
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Getting double for %d,%d from %p", row, column, window);

    field_slot_t field;
    err = window->read_field_slot(row, column, &field);
    if (err != 0) {
        throwExceptionWithRowCol(env, row, column);
        return 0.0;
    }

    uint8_t type = field.type;
    if (type == FIELD_TYPE_FLOAT) {
        double value;
        if (window->getDouble(row, column, &value)) {
            return value;
        }
        return 0.0;
    } else if (type == FIELD_TYPE_STRING) {
        uint32_t size = field.data.buffer.size;
        if (size > 0) {
#if WINDOW_STORAGE_UTF8
            return strtod((char const *)window->offsetToPtr(field.data.buffer.offset), NULL);
#else
            String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
            char const * str = ascii.string();
            return strtod(str, NULL);
#endif
        } else {
            return 0.0;
        }
    } else if (type == FIELD_TYPE_INTEGER) {
        int64_t value;
        if (window->getLong(row, column, &value)) {
            return (double) value;
        }
        return 0.0;
    } else if (type == FIELD_TYPE_NULL) {
        return 0.0;
    } else if (type == FIELD_TYPE_BLOB) {
        throw_sqlite3_exception(env, "Unable to convert BLOB to double");
        return 0.0;
    } else {
        throwUnknowTypeException(env, type);
        return 0.0;
    }
}

static jboolean isNull_native(JNIEnv* env, jobject object, jint row, jint column)
{
    CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Checking for NULL at %d,%d from %p", row, column, window);

    bool isNull;
    if (window->getNull(row, column, &isNull)) {
        return isNull;
    }

    //TODO throw execption?
    return true;
}

static jint getNumRows(JNIEnv * env, jobject object)
{
    CursorWindow * window = GET_WINDOW(env, object);
    return window->getNumRows();
}

static jboolean setNumColumns(JNIEnv * env, jobject object, jint columnNum)
{
    CursorWindow * window = GET_WINDOW(env, object);
    return window->setNumColumns(columnNum);
}

static jboolean allocRow(JNIEnv * env, jobject object)
{
    CursorWindow * window = GET_WINDOW(env, object);
    return window->allocRow() != NULL;
}

static jboolean putBlob_native(JNIEnv * env, jobject object, jbyteArray value, jint row, jint col)
{
    CursorWindow * window = GET_WINDOW(env, object);
    if (!value) {
        LOG_WINDOW("How did a null value send to here");
        return false;
    }
    field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, col);
    if (fieldSlot == NULL) {
        LOG_WINDOW(" getFieldSlotWithCheck error ");
        return false;
    }

    jint len = env->GetArrayLength(value);
    int offset = window->alloc(len);
    if (!offset) {
        LOG_WINDOW("Failed allocating %u bytes", len);
        return false;
    }
    jbyte * bytes = env->GetByteArrayElements(value, NULL);
    window->copyIn(offset, (uint8_t const *)bytes, len);

    // This must be updated after the call to alloc(), since that
    // may move the field around in the window
    fieldSlot->type = FIELD_TYPE_BLOB;
    fieldSlot->data.buffer.offset = offset;
    fieldSlot->data.buffer.size = len;
    env->ReleaseByteArrayElements(value, bytes, JNI_ABORT);
    LOG_WINDOW("%d,%d is BLOB with %u bytes @ %d", row, col, len, offset);
    return true;
}

static jboolean putString_native(JNIEnv * env, jobject object, jstring value, jint row, jint col)
{
    CursorWindow * window = GET_WINDOW(env, object);
    if (!value) {
        LOG_WINDOW("How did a null value send to here");
        return false;
    }
    field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, col);
    if (fieldSlot == NULL) {
        LOG_WINDOW(" getFieldSlotWithCheck error ");
        return false;
    }

#if WINDOW_STORAGE_UTF8
    int len = env->GetStringUTFLength(value) + 1;
    char const * valStr = env->GetStringUTFChars(value, NULL);
#else
    int len = env->GetStringLength(value);
    // GetStringLength return number of chars and one char takes 2 bytes
    len *= 2;
    const jchar* valStr = env->GetStringChars(value, NULL);
#endif
    if (!valStr) {
        LOG_WINDOW("value can't be transfer to UTFChars");
        return false;
    }

    int offset = window->alloc(len);
    if (!offset) {
        LOG_WINDOW("Failed allocating %u bytes", len);
#if WINDOW_STORAGE_UTF8
        env->ReleaseStringUTFChars(value, valStr);
#else
        env->ReleaseStringChars(value, valStr);
#endif
        return false;
    }

    window->copyIn(offset, (uint8_t const *)valStr, len);

    // This must be updated after the call to alloc(), since that
    // may move the field around in the window
    fieldSlot->type = FIELD_TYPE_STRING;
    fieldSlot->data.buffer.offset = offset;
    fieldSlot->data.buffer.size = len;

    LOG_WINDOW("%d,%d is TEXT with %u bytes @ %d", row, col, len, offset);
#if WINDOW_STORAGE_UTF8
    env->ReleaseStringUTFChars(value, valStr);
#else
    env->ReleaseStringChars(value, valStr);
#endif

    return true;
}

static jboolean putLong_native(JNIEnv * env, jobject object, jlong value, jint row, jint col)
{
    CursorWindow * window = GET_WINDOW(env, object);
    if (!window->putLong(row, col, value)) {
        LOG_WINDOW(" getFieldSlotWithCheck error ");
        return false;
    }

    LOG_WINDOW("%d,%d is INTEGER 0x%016llx", row, col, value);

    return true;
}

static jboolean putDouble_native(JNIEnv * env, jobject object, jdouble value, jint row, jint col)
{
    CursorWindow * window = GET_WINDOW(env, object);
    if (!window->putDouble(row, col, value)) {
        LOG_WINDOW(" getFieldSlotWithCheck error ");
        return false;
    }

    LOG_WINDOW("%d,%d is FLOAT %lf", row, col, value);

    return true;
}

static jboolean putNull_native(JNIEnv * env, jobject object, jint row, jint col)
{
    CursorWindow * window = GET_WINDOW(env, object);
    if (!window->putNull(row, col)) {
        LOG_WINDOW(" getFieldSlotWithCheck error ");
        return false;
    }

    LOG_WINDOW("%d,%d is NULL", row, col);

    return true;
}

// free the last row
static void freeLastRow(JNIEnv * env, jobject object) {
    CursorWindow * window = GET_WINDOW(env, object);
    window->freeLastRow();
}

static JNINativeMethod sMethods[] =
{
     /* name, signature, funcPtr */
    {"native_init", "(Z)V", (void *)native_init_empty},
    {"native_init", "(Landroid/os/IBinder;)V", (void *)native_init_memory},
    {"native_getBinder", "()Landroid/os/IBinder;", (void *)native_getBinder},
    {"native_clear", "()V", (void *)native_clear},
    {"close_native", "()V", (void *)native_close},
    {"getLong_native", "(II)J", (void *)getLong_native},
    {"getBlob_native", "(II)[B", (void *)getBlob_native},
    {"isBlob_native", "(II)Z", (void *)isBlob_native},
    {"getString_native", "(II)Ljava/lang/String;", (void *)getString_native},
    {"copyStringToBuffer_native", "(IIILandroid/database/CharArrayBuffer;)[C", (void *)copyStringToBuffer_native},
    {"getDouble_native", "(II)D", (void *)getDouble_native},
    {"isNull_native", "(II)Z", (void *)isNull_native},
    {"getNumRows_native", "()I", (void *)getNumRows},
    {"setNumColumns_native", "(I)Z", (void *)setNumColumns},
    {"allocRow_native", "()Z", (void *)allocRow},
    {"putBlob_native", "([BII)Z", (void *)putBlob_native},
    {"putString_native", "(Ljava/lang/String;II)Z", (void *)putString_native},
    {"putLong_native", "(JII)Z", (void *)putLong_native},
    {"putDouble_native", "(DII)Z", (void *)putDouble_native},
    {"freeLastRow_native", "()V", (void *)freeLastRow},
    {"putNull_native", "(II)Z", (void *)putNull_native},
    {"isString_native", "(II)Z", (void *)isString_native},
    {"isFloat_native", "(II)Z", (void *)isFloat_native},
    {"isInteger_native", "(II)Z", (void *)isInteger_native},
};

int register_android_database_CursorWindow(JNIEnv * env)
{
    jclass clazz;

    clazz = env->FindClass("android/database/CursorWindow");
    if (clazz == NULL) {
        LOGE("Can't find android/database/CursorWindow");
        return -1;
    }

    gWindowField = env->GetFieldID(clazz, "nWindow", "I");

    if (gWindowField == NULL) {
        LOGE("Error locating fields");
        return -1;
    }

    clazz =  env->FindClass("android/database/CharArrayBuffer");
    if (clazz == NULL) {
        LOGE("Can't find android/database/CharArrayBuffer");
        return -1;
    }

    gBufferField = env->GetFieldID(clazz, "data", "[C");

    if (gBufferField == NULL) {
        LOGE("Error locating fields data in CharArrayBuffer");
        return -1;
    }

    gSizeCopiedField = env->GetFieldID(clazz, "sizeCopied", "I");

    if (gSizeCopiedField == NULL) {
        LOGE("Error locating fields sizeCopied in CharArrayBuffer");
        return -1;
    }

    return AndroidRuntime::registerNativeMethods(env, "android/database/CursorWindow",
            sMethods, NELEM(sMethods));
}

} // namespace android
