/*
 * 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 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 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},
};

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
