/*
 * Copyright 2008, 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 "wifi"

#include "jni.h"
#include <ScopedUtfChars.h>
#include <utils/misc.h>
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
#include <utils/String16.h>

#include "wifi.h"
#include "wifi_hal.h"
#include "jni_helper.h"

namespace android {

/* JNI Helpers for wifi_hal implementation */

JNIHelper::JNIHelper(JavaVM *vm)
{
    vm->AttachCurrentThread(&mEnv, NULL);
    mVM = vm;
}

JNIHelper::JNIHelper(JNIEnv *env)
{
    mVM  = NULL;
    mEnv = env;
}

JNIHelper::~JNIHelper()
{
    if (mVM != NULL) {
        // mVM->DetachCurrentThread();  /* 'attempting to detach while still running code' */
        mVM = NULL;                     /* not really required; but may help debugging */
        mEnv = NULL;                    /* not really required; but may help debugging */
    }
}

jobject JNIHelper::newGlobalRef(jobject obj) {
    return mEnv->NewGlobalRef(obj);
}

void JNIHelper::deleteGlobalRef(jobject obj) {
    mEnv->DeleteGlobalRef(obj);
}

jobject JNIHelper::newLocalRef(jobject obj) {
    return mEnv->NewLocalRef(obj);
}

void JNIHelper::deleteLocalRef(jobject obj) {
    mEnv->DeleteLocalRef(obj);
}

void JNIHelper::throwException(const char *message, int line)
{
    ALOGE("error at line %d: %s", line, message);

    const char *className = "java/lang/Exception";

    jclass exClass = mEnv->FindClass(className );
    if ( exClass == NULL ) {
        ALOGE("Could not find exception class to throw error");
        ALOGE("error at line %d: %s", line, message);
        return;
    }

    mEnv->ThrowNew(exClass, message);
}

jboolean JNIHelper::getBoolField(jobject obj, const char *name)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, "Z");
    if (field == 0) {
        THROW(*this, "Error in accessing field");
        return 0;
    }

    return mEnv->GetBooleanField(obj, field);
}

jint JNIHelper::getIntField(jobject obj, const char *name)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, "I");
    if (field == 0) {
        THROW(*this, "Error in accessing field");
        return 0;
    }

    return mEnv->GetIntField(obj, field);
}

jbyte JNIHelper::getByteField(jobject obj, const char *name)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, "B");
    if (field == 0) {
        THROW(*this, "Error in accessing field");
        return 0;
    }

    return mEnv->GetByteField(obj, field);
}

jlong JNIHelper::getLongField(jobject obj, const char *name)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, "J");
    if (field == 0) {
        THROW(*this, "Error in accessing field");
        return 0;
    }

    return mEnv->GetLongField(obj, field);
}

JNIObject<jstring> JNIHelper::getStringField(jobject obj, const char *name)
{
    JNIObject<jobject> m = getObjectField(obj, name, "Ljava/lang/String;");
    if (m == NULL) {
        THROW(*this, "Error in accessing field");
        return JNIObject<jstring>(*this, NULL);
    }

    return JNIObject<jstring>(*this, (jstring)m.detach());
}

bool JNIHelper::getStringFieldValue(jobject obj, const char *name, char *buf, int size)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, "Ljava/lang/String;");
    if (field == 0) {
        THROW(*this, "Error in accessing field");
        return 0;
    }

    JNIObject<jobject> value(*this, mEnv->GetObjectField(obj, field));
    JNIObject<jstring> string(*this, (jstring)value.clone());
    ScopedUtfChars chars(mEnv, string);

    const char *utf = chars.c_str();
    if (utf == NULL) {
        THROW(*this, "Error in accessing value");
        return false;
    }

    if (*utf != 0 && size < 1) {
        return false;
    }

    strncpy(buf, utf, size);
    if (size > 0) {
        buf[size - 1] = 0;
    }

    return true;
}

jlong JNIHelper::getStaticLongField(jobject obj, const char *name)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    return getStaticLongField(cls, name);
}

jlong JNIHelper::getStaticLongField(jclass cls, const char *name)
{
    jfieldID field = mEnv->GetStaticFieldID(cls, name, "J");
    if (field == 0) {
        THROW(*this, "Error in accessing field");
        return 0;
    }
    //ALOGE("getStaticLongField %s %p", name, cls);
    return mEnv->GetStaticLongField(cls, field);
}

JNIObject<jobject> JNIHelper::getObjectField(jobject obj, const char *name, const char *type)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, type);
    if (field == 0) {
        THROW(*this, "Error in accessing field");
        return JNIObject<jobject>(*this, NULL);
    }

    return JNIObject<jobject>(*this, mEnv->GetObjectField(obj, field));
}

JNIObject<jobjectArray> JNIHelper::getArrayField(jobject obj, const char *name, const char *type)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, type);
    if (field == 0) {
        THROW(*this, "Error in accessing field");
        return JNIObject<jobjectArray>(*this, NULL);
    }

    return JNIObject<jobjectArray>(*this, (jobjectArray)mEnv->GetObjectField(obj, field));
}

jlong JNIHelper::getLongArrayField(jobject obj, const char *name, int index)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, "[J");
    if (field == 0) {
        THROW(*this, "Error in accessing field definition");
        return 0;
    }

    JNIObject<jlongArray> array(*this, (jlongArray)mEnv->GetObjectField(obj, field));
    if (array == NULL) {
        THROW(*this, "Error in accessing array");
        return 0;
    }

    jlong *elem = mEnv->GetLongArrayElements(array, 0);
    if (elem == NULL) {
        THROW(*this, "Error in accessing index element");
        return 0;
    }

    jlong value = elem[index];
    mEnv->ReleaseLongArrayElements(array, elem, 0);
    return value;
}

jlong JNIHelper::getStaticLongArrayField(jobject obj, const char *name, int index)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    return getStaticLongArrayField(cls, name, index);
}

jlong JNIHelper::getStaticLongArrayField(jclass cls, const char *name, int index)
{
    jfieldID field = mEnv->GetStaticFieldID(cls, name, "[J");
    if (field == 0) {
        THROW(*this, "Error in accessing field definition");
        return 0;
    }

    JNIObject<jlongArray> array(*this, (jlongArray)mEnv->GetStaticObjectField(cls, field));
    jlong *elem = mEnv->GetLongArrayElements(array, 0);
    if (elem == NULL) {
        THROW(*this, "Error in accessing index element");
        return 0;
    }

    jlong value = elem[index];
    mEnv->ReleaseLongArrayElements(array, elem, 0);
    return value;
}

JNIObject<jobject> JNIHelper::getObjectArrayField(jobject obj, const char *name, const char *type,
int index)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    jfieldID field = mEnv->GetFieldID(cls, name, type);
    if (field == 0) {
        THROW(*this, "Error in accessing field definition");
        return JNIObject<jobject>(*this, NULL);
    }

    JNIObject<jobjectArray> array(*this, (jobjectArray)mEnv->GetObjectField(obj, field));
    JNIObject<jobject> elem(*this, mEnv->GetObjectArrayElement(array, index));
    if (elem.isNull()) {
        THROW(*this, "Error in accessing index element");
        return JNIObject<jobject>(*this, NULL);
    }
    return elem;
}

void JNIHelper::setIntField(jobject obj, const char *name, jint value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing class");
        return;
    }

    jfieldID field = mEnv->GetFieldID(cls, name, "I");
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    mEnv->SetIntField(obj, field, value);
}

void JNIHelper::setByteField(jobject obj, const char *name, jbyte value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing class");
        return;
    }

    jfieldID field = mEnv->GetFieldID(cls, name, "B");
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    mEnv->SetByteField(obj, field, value);
}

void JNIHelper::setBooleanField(jobject obj, const char *name, jboolean value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing class");
        return;
    }

    jfieldID field = mEnv->GetFieldID(cls, name, "Z");
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    mEnv->SetBooleanField(obj, field, value);
}

void JNIHelper::setLongField(jobject obj, const char *name, jlong value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing class");
        return;
    }

    jfieldID field = mEnv->GetFieldID(cls, name, "J");
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    mEnv->SetLongField(obj, field, value);
}

void JNIHelper::setStaticLongField(jobject obj, const char *name, jlong value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing class");
        return;
    }

    setStaticLongField(cls, name, value);
}

void JNIHelper::setStaticLongField(jclass cls, const char *name, jlong value)
{
    jfieldID field = mEnv->GetStaticFieldID(cls, name, "J");
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    mEnv->SetStaticLongField(cls, field, value);
}

void JNIHelper::setLongArrayField(jobject obj, const char *name, jlongArray value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    jfieldID field = mEnv->GetFieldID(cls, name, "[J");
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    mEnv->SetObjectField(obj, field, value);
}

void JNIHelper::setStaticLongArrayField(jobject obj, const char *name, jlongArray value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    setStaticLongArrayField(cls, name, value);
}

void JNIHelper::setStaticLongArrayField(jclass cls, const char *name, jlongArray value)
{
    jfieldID field = mEnv->GetStaticFieldID(cls, name, "[J");
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    mEnv->SetStaticObjectField(cls, field, value);
    ALOGD("array field set");
}

void JNIHelper::setLongArrayElement(jobject obj, const char *name, int index, jlong value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    jfieldID field = mEnv->GetFieldID(cls, name, "[J");
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    JNIObject<jlongArray> array(*this, (jlongArray)mEnv->GetObjectField(obj, field));
    if (array == NULL) {
        THROW(*this, "Error in accessing array");
        return;
    }

    jlong *elem = mEnv->GetLongArrayElements(array, NULL);
    if (elem == NULL) {
        THROW(*this, "Error in accessing index element");
        return;
    }

    elem[index] = value;
    mEnv->ReleaseLongArrayElements(array, elem, 0);
}

void JNIHelper::setObjectField(jobject obj, const char *name, const char *type, jobject value)
{
    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
    if (cls == NULL) {
        THROW(*this, "Error in accessing class");
        return;
    }

    jfieldID field = mEnv->GetFieldID(cls, name, type);
    if (field == NULL) {
        THROW(*this, "Error in accessing field");
        return;
    }

    mEnv->SetObjectField(obj, field, value);
}

jboolean JNIHelper::setStringField(jobject obj, const char *name, const char *value)
{
    JNIObject<jstring> str(*this, mEnv->NewStringUTF(value));

    if (mEnv->ExceptionCheck()) {
        mEnv->ExceptionDescribe();
        mEnv->ExceptionClear();
        return false;
    }

    if (str == NULL) {
        THROW(*this, "Error creating string");
        return false;
    }

    setObjectField(obj, name, "Ljava/lang/String;", str);
    return true;
}

void JNIHelper::reportEvent(jclass cls, const char *method, const char *signature, ...)
{
    va_list params;
    va_start(params, signature);

    jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature);
    if (methodID == 0) {
        ALOGE("Error in getting method ID");
        return;
    }

    mEnv->CallStaticVoidMethodV(cls, methodID, params);
    if (mEnv->ExceptionCheck()) {
        mEnv->ExceptionDescribe();
        mEnv->ExceptionClear();
    }

    va_end(params);
}

jboolean JNIHelper::callStaticMethod(jclass cls, const char *method, const char *signature, ...)
{
    va_list params;
    va_start(params, signature);

    jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature);
    if (methodID == 0) {
        ALOGE("Error in getting method ID");
        return false;
    }

    jboolean result = mEnv->CallStaticBooleanMethodV(cls, methodID, params);
    if (mEnv->ExceptionCheck()) {
        mEnv->ExceptionDescribe();
        mEnv->ExceptionClear();
        return false;
    }

    va_end(params);
    return result;
}

JNIObject<jobject> JNIHelper::createObject(const char *className)
{
    JNIObject<jclass> cls(*this, mEnv->FindClass(className));
    if (cls == NULL) {
        ALOGE("Error in finding class %s", className);
        return JNIObject<jobject>(*this, NULL);
    }

    jmethodID constructor = mEnv->GetMethodID(cls, "<init>", "()V");
    if (constructor == 0) {
        ALOGE("Error in constructor ID for %s", className);
        return JNIObject<jobject>(*this, NULL);
    }

    JNIObject<jobject> obj(*this, mEnv->NewObject(cls, constructor));
    if (obj == NULL) {
        ALOGE("Could not create new object of %s", className);
        return JNIObject<jobject>(*this, NULL);
    }

    return obj;
}

JNIObject<jobjectArray> JNIHelper::createObjectArray(const char *className, int num)
{
    JNIObject<jclass> cls(*this, mEnv->FindClass(className));
    if (cls == NULL) {
        ALOGE("Error in finding class %s", className);
        return JNIObject<jobjectArray>(*this, NULL);
    }

    JNIObject<jobject> array(*this, mEnv->NewObjectArray(num, cls.get(), NULL));
    if (array.get() == NULL) {
        ALOGE("Error in creating array of class %s", className);
        return JNIObject<jobjectArray>(*this, NULL);
    }

    return JNIObject<jobjectArray>(*this, (jobjectArray)array.detach());
}

JNIObject<jobject> JNIHelper::getObjectArrayElement(jobjectArray array, int index)
{
    return JNIObject<jobject>(*this, mEnv->GetObjectArrayElement(array, index));
}

JNIObject<jobject> JNIHelper::getObjectArrayElement(jobject array, int index)
{
    return getObjectArrayElement((jobjectArray)array, index);
}

int JNIHelper::getArrayLength(jarray array) {
    return mEnv->GetArrayLength(array);
}

JNIObject<jobjectArray> JNIHelper::newObjectArray(int num, const char *className, jobject val) {
    JNIObject<jclass> cls(*this, mEnv->FindClass(className));
    if (cls == NULL) {
        ALOGE("Error in finding class %s", className);
        return JNIObject<jobjectArray>(*this, NULL);
    }

    return JNIObject<jobjectArray>(*this, mEnv->NewObjectArray(num, cls, val));
}

JNIObject<jbyteArray> JNIHelper::newByteArray(int num) {
    return JNIObject<jbyteArray>(*this, mEnv->NewByteArray(num));
}

JNIObject<jintArray> JNIHelper::newIntArray(int num) {
    return JNIObject<jintArray>(*this, mEnv->NewIntArray(num));
}

JNIObject<jlongArray> JNIHelper::newLongArray(int num) {
    return JNIObject<jlongArray>(*this, mEnv->NewLongArray(num));
}

JNIObject<jstring> JNIHelper::newStringUTF(const char *utf) {
    return JNIObject<jstring>(*this, mEnv->NewStringUTF(utf));
}

void JNIHelper::setObjectArrayElement(jobjectArray array, int index, jobject obj) {
    mEnv->SetObjectArrayElement(array, index, obj);
}

void JNIHelper::setByteArrayRegion(jbyteArray array, int from, int to, jbyte *bytes) {
    mEnv->SetByteArrayRegion(array, from, to, bytes);
}

void JNIHelper::setIntArrayRegion(jintArray array, int from, int to, jint *ints) {
    mEnv->SetIntArrayRegion(array, from, to, ints);
}

void JNIHelper::setLongArrayRegion(jlongArray array, int from, int to, jlong *longs) {
    mEnv->SetLongArrayRegion(array, from, to, longs);
}

}; // namespace android


