/*
 * Copyright (C) 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 "PlatformLibrary"
#include "utils/Log.h"

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>

#include "jni.h"


// ----------------------------------------------------------------------------

/*
 * Field/method IDs and class object references.
 *
 * You should not need to store the JNIEnv pointer in here.  It is
 * thread-specific and will be passed back in on every call.
 */
static struct {
    jclass      platformLibraryClass;
    jfieldID    jniInt;
    jmethodID   yodel;
} gCachedState;

// ----------------------------------------------------------------------------

/*
 * Helper function to throw an arbitrary exception.
 *
 * Takes the exception class name, a format string, and one optional integer
 * argument (useful for including an error code, perhaps from errno).
 */
static void throwException(JNIEnv* env, const char* ex, const char* fmt,
    int data) {

    if (jclass cls = env->FindClass(ex)) {
        if (fmt != NULL) {
            char msg[1000];
            snprintf(msg, sizeof(msg), fmt, data);
            env->ThrowNew(cls, msg);
        } else {
            env->ThrowNew(cls, NULL);
        }

        /*
         * This is usually not necessary -- local references are released
         * automatically when the native code returns to the VM.  It's
         * required if the code doesn't actually return, e.g. it's sitting
         * in a native event loop.
         */
        env->DeleteLocalRef(cls);
    }
}

/*
 * Trivial sample method.
 *
 * If "bad" is true, this throws an exception.  Otherwise, this sets the
 * "mJniInt" field to 42 and returns 24.
 */
static jint PlatformLibrary_getJniInt(JNIEnv* env, jobject thiz, jboolean bad) {
    if (bad) {
        throwException(env, "java/lang/IllegalStateException",
                "you are bad", 0);
        return 0;       /* return value will be ignored */
    }
    env->SetIntField(thiz, gCachedState.jniInt, 42);
    return (jint)24;
}

/*
 * A more complex sample method.
 *
 * This takes a String as an argument, and returns a new String with
 * characters in reverse order.  The new string is passed to another method.
 * This demonstrates basic String manipulation functions and method
 * invocation.
 *
 * This method is declared "static", so there's no "this" pointer; instead,
 * we get a pointer to the class object.
 */
static jstring PlatformLibrary_reverseString(JNIEnv* env, jclass clazz,
    jstring str) {

    if (str == NULL) {
        throwException(env, "java/lang/NullPointerException", NULL, 0);
        return NULL;
    }

    /*
     * Get a pointer to the string's UTF-16 character data.  The data
     * may be a copy or a pointer to the original.  Since String data
     * is immutable, we're not allowed to touch it.
     */
    const jchar* strChars = env->GetStringChars(str, NULL);
    if (strChars == NULL) {
        /* something went wrong */
        ALOGW("Couldn't get string chars\n");
        return NULL;
    }
    jsize strLength = env->GetStringLength(str);

    /*
     * Write a progress message to the log.  Log messages are UTF-8, so
     * we want to convert the string to show it.
     */
    const char* printable = env->GetStringUTFChars(str, NULL);
    if (printable != NULL) {
        ALOGD("Reversing string '%s'\n", printable);
        env->ReleaseStringUTFChars(str, printable);
    }

    /*
     * Copy the characters to temporary storage, reversing as we go.
     */
    jchar tempChars[strLength];
    for (int i = 0; i < strLength; i++) {
        tempChars[i] = strChars[strLength -1 -i];
    }

    /*
     * Release the original String.  That way, if something fails later on,
     * we don't have to worry about this leading to a memory leak.
     */
    env->ReleaseStringChars(str, strChars);
    strChars = NULL;            /* this pointer no longer valid */

    /*
     * Create a new String with the chars.
     */
    jstring result = env->NewString(tempChars, strLength);
    if (result == NULL) {
        ALOGE("NewString failed\n");
        return NULL;
    }

    /*
     * Now let's do something with it.  We already have the methodID for
     * "yodel", so we can invoke it directly.  It's in our class, so we
     * can use the Class object reference that was passed in.
     */
    env->CallStaticVoidMethod(clazz, gCachedState.yodel, result);

    return result;
}


// ----------------------------------------------------------------------------

/*
 * Array of methods.
 *
 * Each entry has three fields: the name of the method, the method
 * signature, and a pointer to the native implementation.
 */
static const JNINativeMethod gMethods[] = {
    { "getJniInt",          "(Z)I",
                        (void*)PlatformLibrary_getJniInt },
    { "reverseString",      "(Ljava/lang/String;)Ljava/lang/String;",
                        (void*)PlatformLibrary_reverseString },
};

/*
 * Do some (slow-ish) lookups now and save the results.
 *
 * Returns 0 on success.
 */
static int cacheIds(JNIEnv* env, jclass clazz) {
    /*
     * Save the class in case we want to use it later.  Because this is a
     * reference to the Class object, we need to convert it to a JNI global
     * reference.
     */
    gCachedState.platformLibraryClass = (jclass) env->NewGlobalRef(clazz);
    if (clazz == NULL) {
        ALOGE("Can't create new global ref\n");
        return -1;
    }

    /*
     * Cache field and method IDs.  IDs are not references, which means we
     * don't need to call NewGlobalRef on them.
     */
    gCachedState.jniInt = env->GetFieldID(clazz, "mJniInt", "I");
    if (gCachedState.jniInt == NULL) {
        ALOGE("Can't find PlatformLibrary.mJniInt\n");
        return -1;
    }

    gCachedState.yodel = env->GetStaticMethodID(clazz, "yodel",
        "(Ljava/lang/String;)V");
    if (gCachedState.yodel == NULL) {
        ALOGE("Can't find PlatformLibrary.yodel\n");
        return -1;
    }

    return 0;
}

/*
 * Explicitly register all methods for our class.
 *
 * While we're at it, cache some class references and method/field IDs.
 *
 * Returns 0 on success.
 */
static int registerMethods(JNIEnv* env) {
    static const char* const kClassName =
        "com/example/android/platform_library/PlatformLibrary";
    jclass clazz;

    /* look up the class */
    clazz = env->FindClass(kClassName);
    if (clazz == NULL) {
        ALOGE("Can't find class %s\n", kClassName);
        return -1;
    }

    /* register all the methods */
    if (env->RegisterNatives(clazz, gMethods,
            sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
    {
        ALOGE("Failed registering methods for %s\n", kClassName);
        return -1;
    }

    /* fill out the rest of the ID cache */
    return cacheIds(env, clazz);
}

// ----------------------------------------------------------------------------

/*
 * This is called by the VM when the shared library is first loaded.
 */
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("ERROR: GetEnv failed\n");
        goto bail;
    }
    assert(env != NULL);

    if (registerMethods(env) != 0) {
        ALOGE("ERROR: PlatformLibrary native registration failed\n");
        goto bail;
    }

    /* success -- return valid version number */
    result = JNI_VERSION_1_4;

bail:
    return result;
}
