/*
 * Copyright (C) 2012, Collabora Ltd.
 *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * Copyright (C) 2013, Fluendo S.A.
 *   Author: Andoni Morales <amorales@fluendo.com>
 * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
 * Copyright (C) 2014, Collabora Ltd.
 *   Author: Matthieu Bouron <matthieu.bouron@collabora.com>
 * Copyright (C) 2015, Sebastian Dröge <sebastian@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>
#include <pthread.h>
#include <gmodule.h>

#include "gstjniutils.h"

static GModule *java_module;
static jint (*get_created_java_vms) (JavaVM ** vmBuf, jsize bufLen,
    jsize * nVMs);
static jint (*create_java_vm) (JavaVM ** p_vm, JNIEnv ** p_env, void *vm_args);
static JavaVM *java_vm;
static gboolean started_java_vm = FALSE;
static pthread_key_t current_jni_env;

static struct
{
  jclass klass;
  jmethodID get_limit, get_position;
  jmethodID set_limit, set_position;
  jmethodID clear;
} java_nio_buffer;

jclass
gst_amc_jni_get_class (JNIEnv * env, GError ** err, const gchar * name)
{
  jclass tmp, ret = NULL;

  GST_DEBUG ("Retrieving Java class %s", name);

  tmp = (*env)->FindClass (env, name);
  if ((*env)->ExceptionCheck (env) || !tmp) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to find class %s", name);
    goto done;
  }

  ret = (*env)->NewGlobalRef (env, tmp);
  if (!ret) {
    GST_ERROR ("Failed to get %s class global reference", name);
  }

done:
  if (tmp)
    (*env)->DeleteLocalRef (env, tmp);
  tmp = NULL;

  return ret;
}

jmethodID
gst_amc_jni_get_method_id (JNIEnv * env, GError ** err, jclass klass,
    const gchar * name, const gchar * signature)
{
  jmethodID ret;

  ret = (*env)->GetMethodID (env, klass, name, signature);
  if ((*env)->ExceptionCheck (env) || !ret) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to get method ID %s (%s)", name,
        signature);
  }
  return ret;
}

jmethodID
gst_amc_jni_get_static_method_id (JNIEnv * env, GError ** err, jclass klass,
    const gchar * name, const gchar * signature)
{
  jmethodID ret;

  ret = (*env)->GetStaticMethodID (env, klass, name, signature);
  if ((*env)->ExceptionCheck (env) || !ret) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to get static method ID %s (%s)",
        name, signature);
  }
  return ret;
}

jfieldID
gst_amc_jni_get_field_id (JNIEnv * env, GError ** err, jclass klass,
    const gchar * name, const gchar * type)
{
  jfieldID ret;

  ret = (*env)->GetFieldID (env, klass, name, type);
  if ((*env)->ExceptionCheck (env) || !ret) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to get field ID %s (%s)", name, type);
  }
  return ret;
}

jfieldID
gst_amc_jni_get_static_field_id (JNIEnv * env, GError ** err, jclass klass,
    const gchar * name, const gchar * type)
{
  jfieldID ret;

  ret = (*env)->GetStaticFieldID (env, klass, name, type);
  if ((*env)->ExceptionCheck (env) || !ret) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to get static field ID %s (%s)", name,
        type);
  }
  return ret;
}

jobject
gst_amc_jni_new_object (JNIEnv * env, GError ** err, gboolean global,
    jclass klass, jmethodID constructor, ...)
{
  jobject tmp;
  va_list args;

  va_start (args, constructor);
  tmp = (*env)->NewObjectV (env, klass, constructor, args);
  va_end (args);

  if ((*env)->ExceptionCheck (env) || !tmp) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to create object");
    return NULL;
  }

  if (global)
    return gst_amc_jni_object_make_global (env, tmp);
  else
    return tmp;
}

jobject
gst_amc_jni_new_object_from_static (JNIEnv * env, GError ** err,
    gboolean global, jclass klass, jmethodID method, ...)
{
  jobject tmp;
  va_list args;

  va_start (args, method);
  tmp = (*env)->CallStaticObjectMethodV (env, klass, method, args);
  va_end (args);

  if ((*env)->ExceptionCheck (env) || !tmp) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to create object");
    return NULL;
  }

  if (global)
    return gst_amc_jni_object_make_global (env, tmp);
  else
    return tmp;
}

jobject
gst_amc_jni_object_make_global (JNIEnv * env, jobject object)
{
  jobject ret;

  ret = (*env)->NewGlobalRef (env, object);
  if (!ret) {
    GST_ERROR ("Failed to create global reference");
  }
  gst_amc_jni_object_local_unref (env, object);

  return ret;
}

jobject
gst_amc_jni_object_ref (JNIEnv * env, jobject object)
{
  jobject ret;

  ret = (*env)->NewGlobalRef (env, object);
  if (!ret) {
    GST_ERROR ("Failed to create global reference");
  }
  return ret;
}

void
gst_amc_jni_object_unref (JNIEnv * env, jobject object)
{
  (*env)->DeleteGlobalRef (env, object);
}

void
gst_amc_jni_object_local_unref (JNIEnv * env, jobject object)
{
  (*env)->DeleteLocalRef (env, object);
}

jstring
gst_amc_jni_string_from_gchar (JNIEnv * env, GError ** err,
    gboolean global, const gchar * string)
{
  jstring tmp;

  tmp = (*env)->NewStringUTF (env, string);
  if ((*env)->ExceptionCheck (env)) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to call Java method");
    tmp = NULL;
  }

  if (global)
    return gst_amc_jni_object_make_global (env, tmp);
  else
    return tmp;
}

gchar *
gst_amc_jni_string_to_gchar (JNIEnv * env, jstring string, gboolean release)
{
  const gchar *s = NULL;
  gchar *ret = NULL;

  s = (*env)->GetStringUTFChars (env, string, NULL);
  if (!s) {
    GST_ERROR ("Failed to convert string to UTF8");
    goto done;
  }

  ret = g_strdup (s);
  (*env)->ReleaseStringUTFChars (env, string, s);

done:
  if (release) {
    (*env)->DeleteLocalRef (env, string);
  }
  return ret;
}

/* getExceptionSummary() and getStackTrace() taken from Android's
 *   platform/libnativehelper/JNIHelp.cpp
 * Modified to work with normal C strings and without C++.
 *
 * Copyright (C) 2006 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.
 */

/*
 * Returns a human-readable summary of an exception object. The buffer will
 * be populated with the "binary" class name and, if present, the
 * exception message.
 */
static gchar *
getExceptionSummary (JNIEnv * env, jthrowable exception)
{
  GString *gs = g_string_new ("");
  jclass exceptionClass = NULL, classClass = NULL;
  jmethodID classGetNameMethod, getMessage;
  jstring classNameStr = NULL, messageStr = NULL;
  const char *classNameChars, *messageChars;

  /* get the name of the exception's class */
  exceptionClass = (*env)->GetObjectClass (env, exception);
  classClass = (*env)->GetObjectClass (env, exceptionClass);
  classGetNameMethod =
      (*env)->GetMethodID (env, classClass, "getName", "()Ljava/lang/String;");

  classNameStr =
      (jstring) (*env)->CallObjectMethod (env, exceptionClass,
      classGetNameMethod);

  if (classNameStr == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error getting class name>");
    goto done;
  }

  classNameChars = (*env)->GetStringUTFChars (env, classNameStr, NULL);
  if (classNameChars == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error getting class name UTF-8>");
    goto done;
  }

  g_string_append (gs, classNameChars);

  (*env)->ReleaseStringUTFChars (env, classNameStr, classNameChars);

  /* if the exception has a detail message, get that */
  getMessage =
      (*env)->GetMethodID (env, exceptionClass, "getMessage",
      "()Ljava/lang/String;");
  messageStr = (jstring) (*env)->CallObjectMethod (env, exception, getMessage);
  if (messageStr == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    goto done;
  }
  g_string_append (gs, ": ");

  messageChars = (*env)->GetStringUTFChars (env, messageStr, NULL);
  if (messageChars != NULL) {
    g_string_append (gs, messageChars);
    (*env)->ReleaseStringUTFChars (env, messageStr, messageChars);
  } else {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error getting message>");
  }

done:
  if (exceptionClass)
    (*env)->DeleteLocalRef (env, exceptionClass);
  if (classClass)
    (*env)->DeleteLocalRef (env, classClass);
  if (classNameStr)
    (*env)->DeleteLocalRef (env, classNameStr);
  if (messageStr)
    (*env)->DeleteLocalRef (env, messageStr);

  return g_string_free (gs, FALSE);
}

/*
 * Returns an exception (with stack trace) as a string.
 */
static gchar *
getStackTrace (JNIEnv * env, jthrowable exception)
{
  GString *gs = g_string_new ("");
  jclass stringWriterClass = NULL, printWriterClass = NULL;
  jclass exceptionClass = NULL;
  jmethodID stringWriterCtor, stringWriterToStringMethod;
  jmethodID printWriterCtor, printStackTraceMethod;
  jobject stringWriter = NULL, printWriter = NULL;
  jstring messageStr = NULL;
  const char *utfChars;

  stringWriterClass = (*env)->FindClass (env, "java/io/StringWriter");

  if (stringWriterClass == NULL) {
    g_string_append (gs, "<error getting java.io.StringWriter class>");
    goto done;
  }

  stringWriterCtor =
      (*env)->GetMethodID (env, stringWriterClass, "<init>", "()V");
  stringWriterToStringMethod =
      (*env)->GetMethodID (env, stringWriterClass, "toString",
      "()Ljava/lang/String;");

  printWriterClass = (*env)->FindClass (env, "java/io/PrintWriter");
  if (printWriterClass == NULL) {
    g_string_append (gs, "<error getting java.io.PrintWriter class>");
    goto done;
  }

  printWriterCtor =
      (*env)->GetMethodID (env, printWriterClass, "<init>",
      "(Ljava/io/Writer;)V");
  stringWriter = (*env)->NewObject (env, stringWriterClass, stringWriterCtor);
  if (stringWriter == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error creating new StringWriter instance>");
    goto done;
  }

  printWriter =
      (*env)->NewObject (env, printWriterClass, printWriterCtor, stringWriter);
  if (printWriter == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error creating new PrintWriter instance>");
    goto done;
  }

  exceptionClass = (*env)->GetObjectClass (env, exception);
  printStackTraceMethod =
      (*env)->GetMethodID (env, exceptionClass, "printStackTrace",
      "(Ljava/io/PrintWriter;)V");
  (*env)->CallVoidMethod (env, exception, printStackTraceMethod, printWriter);
  if ((*env)->ExceptionCheck (env)) {
    (*env)->ExceptionClear (env);
    g_string_append (gs, "<exception while printing stack trace>");
    goto done;
  }

  messageStr = (jstring) (*env)->CallObjectMethod (env, stringWriter,
      stringWriterToStringMethod);
  if (messageStr == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<failed to call StringWriter.toString()>");
    goto done;
  }

  utfChars = (*env)->GetStringUTFChars (env, messageStr, NULL);
  if (utfChars == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<failed to get UTF chars for message>");
    goto done;
  }

  g_string_append (gs, utfChars);

  (*env)->ReleaseStringUTFChars (env, messageStr, utfChars);

done:
  if (stringWriterClass)
    (*env)->DeleteLocalRef (env, stringWriterClass);
  if (printWriterClass)
    (*env)->DeleteLocalRef (env, printWriterClass);
  if (exceptionClass)
    (*env)->DeleteLocalRef (env, exceptionClass);
  if (stringWriter)
    (*env)->DeleteLocalRef (env, stringWriter);
  if (printWriter)
    (*env)->DeleteLocalRef (env, printWriter);
  if (messageStr)
    (*env)->DeleteLocalRef (env, messageStr);

  return g_string_free (gs, FALSE);
}

static JNIEnv *
gst_amc_jni_attach_current_thread (void)
{
  JNIEnv *env;
  JavaVMAttachArgs args;
  gint ret;

  GST_DEBUG ("Attaching thread %p", g_thread_self ());
  args.version = JNI_VERSION_1_6;
  args.name = NULL;
  args.group = NULL;

  if ((ret = (*java_vm)->AttachCurrentThread (java_vm, &env, &args)) != JNI_OK) {
    GST_ERROR ("Failed to attach current thread: %d", ret);
    return NULL;
  }

  return env;
}

static void
gst_amc_jni_detach_current_thread (void *env)
{
  gint ret;

  GST_DEBUG ("Detaching thread %p", g_thread_self ());
  if ((ret = (*java_vm)->DetachCurrentThread (java_vm)) != JNI_OK) {
    GST_DEBUG ("Failed to detach current thread: %d", ret);
  }
}

static gboolean
check_nativehelper (void)
{
  GModule *module;
  void **jni_invocation = NULL;
  gboolean ret = FALSE;

  module = g_module_open (NULL, G_MODULE_BIND_LOCAL);
  if (!module)
    return ret;

  /* Check if libnativehelper is loaded in the process and if
   * it has these awful wrappers for JNI_CreateJavaVM and
   * JNI_GetCreatedJavaVMs that crash the app if you don't
   * create a JniInvocation instance first. If it isn't we
   * just fail here and don't initialize anything.
   * See this code for reference:
   * https://android.googlesource.com/platform/libnativehelper/+/master/JniInvocation.cpp
   */
  if (!g_module_symbol (module, "_ZN13JniInvocation15jni_invocation_E",
          (gpointer *) & jni_invocation)) {
    ret = TRUE;
  } else {
    ret = (jni_invocation != NULL && *jni_invocation != NULL);
  }

  g_module_close (module);

  return ret;
}

static gboolean
load_java_module (const gchar * name)
{
  java_module = g_module_open (name, G_MODULE_BIND_LOCAL);
  if (!java_module)
    goto load_failed;

  if (!g_module_symbol (java_module, "JNI_CreateJavaVM",
          (gpointer *) & create_java_vm)) {
    GST_ERROR ("Could not find 'JNI_CreateJavaVM' in '%s': %s",
        GST_STR_NULL (name), g_module_error ());
    create_java_vm = NULL;
  }

  if (!g_module_symbol (java_module, "JNI_GetCreatedJavaVMs",
          (gpointer *) & get_created_java_vms))
    goto symbol_error;

  return TRUE;

load_failed:
  {
    GST_ERROR ("Failed to load Java module '%s': %s", GST_STR_NULL (name),
        g_module_error ());
    return FALSE;
  }
symbol_error:
  {
    GST_ERROR ("Failed to locate required JNI symbols in '%s': %s",
        GST_STR_NULL (name), g_module_error ());
    g_module_close (java_module);
    java_module = NULL;
    return FALSE;
  }
}

static gboolean
initialize_classes (void)
{
  JNIEnv *env;
  GError *err = NULL;

  env = gst_amc_jni_get_env ();

  java_nio_buffer.klass = gst_amc_jni_get_class (env, &err, "java/nio/Buffer");
  if (!java_nio_buffer.klass) {
    GST_ERROR ("Failed to get java.nio.Buffer class: %s", err->message);
    g_clear_error (&err);
    return FALSE;
  }

  java_nio_buffer.get_limit =
      gst_amc_jni_get_method_id (env, &err, java_nio_buffer.klass, "limit",
      "()I");
  if (!java_nio_buffer.get_limit) {
    GST_ERROR ("Failed to get java.nio.Buffer limit(): %s", err->message);
    g_clear_error (&err);
    return FALSE;
  }

  java_nio_buffer.get_position =
      gst_amc_jni_get_method_id (env, &err, java_nio_buffer.klass, "position",
      "()I");
  if (!java_nio_buffer.get_position) {
    GST_ERROR ("Failed to get java.nio.Buffer position(): %s", err->message);
    g_clear_error (&err);
    return FALSE;
  }

  java_nio_buffer.set_limit =
      gst_amc_jni_get_method_id (env, &err, java_nio_buffer.klass, "limit",
      "(I)Ljava/nio/Buffer;");
  if (!java_nio_buffer.set_limit) {
    GST_ERROR ("Failed to get java.nio.Buffer limit(): %s", err->message);
    g_clear_error (&err);
    return FALSE;
  }

  java_nio_buffer.set_position =
      gst_amc_jni_get_method_id (env, &err, java_nio_buffer.klass, "position",
      "(I)Ljava/nio/Buffer;");
  if (!java_nio_buffer.set_position) {
    GST_ERROR ("Failed to get java.nio.Buffer position(): %s", err->message);
    g_clear_error (&err);
    return FALSE;
  }

  java_nio_buffer.clear =
      gst_amc_jni_get_method_id (env, &err, java_nio_buffer.klass, "clear",
      "()Ljava/nio/Buffer;");
  if (!java_nio_buffer.clear) {
    GST_ERROR ("Failed to get java.nio.Buffer clear(): %s", err->message);
    g_clear_error (&err);
    return FALSE;
  }

  return TRUE;
}

static gboolean
gst_amc_jni_initialize_java_vm (void)
{
  jsize n_vms;
  gint ret;

  if (java_vm) {
    GST_DEBUG ("Java VM already provided by the application");
    return initialize_classes ();
  }

  /* Returns TRUE if we can safely
   * a) get the current VMs and
   * b) start a VM if none is started yet
   *
   * FIXME: On Android >= 4.4 we won't be able to safely start a
   * VM on our own without using private C++ API!
   */
  if (!check_nativehelper ()) {
    GST_ERROR ("Can't safely check for VMs or start a VM");
    return FALSE;
  }

  if (!load_java_module (NULL)) {
    if (!load_java_module ("libdvm"))
      return FALSE;
  }

  n_vms = 0;
  if ((ret = get_created_java_vms (&java_vm, 1, &n_vms)) != JNI_OK)
    goto get_created_failed;

  if (n_vms > 0) {
    GST_DEBUG ("Successfully got existing Java VM %p", java_vm);
  } else if (create_java_vm) {
    JNIEnv *env;
    JavaVMInitArgs vm_args;
    JavaVMOption options[4];

    GST_DEBUG ("Found no existing Java VM, trying to start one");

    options[0].optionString = "-verbose:jni";
    options[1].optionString = "-verbose:gc";
    options[2].optionString = "-Xcheck:jni";
    options[3].optionString = "-Xdebug";

    vm_args.version = JNI_VERSION_1_4;
    vm_args.options = options;
    vm_args.nOptions = 4;
    vm_args.ignoreUnrecognized = JNI_TRUE;
    if ((ret = create_java_vm (&java_vm, &env, &vm_args)) != JNI_OK)
      goto create_failed;
    GST_DEBUG ("Successfully created Java VM %p", java_vm);

    started_java_vm = TRUE;
  } else {
    GST_ERROR ("JNI_CreateJavaVM not available");
    java_vm = NULL;
  }

  if (java_vm == NULL)
    return FALSE;

  return initialize_classes ();

get_created_failed:
  {
    GST_ERROR ("Failed to get already created VMs: %d", ret);
    g_module_close (java_module);
    java_module = NULL;
    return FALSE;
  }
create_failed:
  {
    GST_ERROR ("Failed to create a Java VM: %d", ret);
    g_module_close (java_module);
    java_module = NULL;
    return FALSE;
  }
}

static void
gst_amc_jni_set_error_string (JNIEnv * env, GError ** err, GQuark domain,
    gint code, const gchar * message)
{
  jthrowable exception;

  if (!err) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    return;
  }

  if ((*env)->ExceptionCheck (env)) {
    if ((exception = (*env)->ExceptionOccurred (env))) {
      gchar *exception_description, *exception_stacktrace;

      /* Clear exception so that we can call Java methods again */
      (*env)->ExceptionClear (env);

      exception_description = getExceptionSummary (env, exception);
      exception_stacktrace = getStackTrace (env, exception);
      g_set_error (err, domain, code, "%s: %s\n%s", message,
          exception_description, exception_stacktrace);
      g_free (exception_description);
      g_free (exception_stacktrace);

      (*env)->DeleteLocalRef (env, exception);
    } else {
      (*env)->ExceptionClear (env);
      g_set_error (err, domain, code, "%s", message);
    }
  } else {
    g_set_error (err, domain, code, "%s", message);
  }
}

G_GNUC_PRINTF (5, 6)
     void gst_amc_jni_set_error (JNIEnv * env, GError ** err, GQuark domain,
    gint code, const gchar * format, ...)
{
  gchar *message;
  va_list var_args;

  va_start (var_args, format);
  message = g_strdup_vprintf (format, var_args);
  va_end (var_args);

  gst_amc_jni_set_error_string (env, err, domain, code, message);

  g_free (message);
}

static gpointer
gst_amc_jni_initialize_internal (gpointer data)
{
  pthread_key_create (&current_jni_env, gst_amc_jni_detach_current_thread);
  return gst_amc_jni_initialize_java_vm ()? GINT_TO_POINTER (1) : NULL;
}

/* Allow the application to set the Java VM */
void
gst_amc_jni_set_java_vm (JavaVM * vm)
{
  GST_DEBUG ("Application provides Java VM %p", vm);
  java_vm = vm;
}

gboolean
gst_amc_jni_initialize (void)
{
  GOnce once = G_ONCE_INIT;

  g_once (&once, gst_amc_jni_initialize_internal, NULL);
  return once.retval != NULL;
}

JNIEnv *
gst_amc_jni_get_env (void)
{
  JNIEnv *env;

  if ((env = pthread_getspecific (current_jni_env)) == NULL) {
    env = gst_amc_jni_attach_current_thread ();
    pthread_setspecific (current_jni_env, env);
  }

  return env;
}

gboolean
gst_amc_jni_is_vm_started (void)
{
  return started_java_vm;
}

#define CALL_STATIC_TYPE_METHOD(_type, _name,  _jname)                                                     \
gboolean gst_amc_jni_call_static_##_name##_method (JNIEnv *env, GError ** err, jclass klass, jmethodID methodID, _type * value, ...)   \
  {                                                                                                          \
    gboolean ret = TRUE;                                                                                     \
    va_list args;                                                                                            \
    va_start(args, value);                                                                                \
    *value = (*env)->CallStatic##_jname##MethodV(env, klass, methodID, args);                                \
    if ((*env)->ExceptionCheck (env)) {                                                                      \
      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                               \
          "Failed to call static Java method");                                                         \
      ret = FALSE;                                                                                           \
    }                                                                                                        \
    va_end(args);                                                                                            \
    return ret;                                                                                              \
  }

CALL_STATIC_TYPE_METHOD (gboolean, boolean, Boolean);
CALL_STATIC_TYPE_METHOD (gint8, byte, Byte);
CALL_STATIC_TYPE_METHOD (gshort, short, Short);
CALL_STATIC_TYPE_METHOD (gint, int, Int);
CALL_STATIC_TYPE_METHOD (gchar, char, Char);
CALL_STATIC_TYPE_METHOD (gint64, long, Long);
CALL_STATIC_TYPE_METHOD (gfloat, float, Float);
CALL_STATIC_TYPE_METHOD (gdouble, double, Double);
CALL_STATIC_TYPE_METHOD (jobject, object, Object);

gboolean
gst_amc_jni_call_static_void_method (JNIEnv * env, GError ** err, jclass klass,
    jmethodID methodID, ...)
{
  gboolean ret = TRUE;
  va_list args;
  va_start (args, methodID);

  (*env)->CallStaticVoidMethodV (env, klass, methodID, args);
  if ((*env)->ExceptionCheck (env)) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to call static Java method");
    ret = FALSE;
  }
  va_end (args);
  return ret;
}

#define CALL_TYPE_METHOD(_type, _name,  _jname)                                                              \
gboolean gst_amc_jni_call_##_name##_method (JNIEnv *env, GError ** err, jobject obj, jmethodID methodID, _type *value, ...)   \
  {                                                                                                          \
    gboolean ret = TRUE;                                                                                     \
    va_list args;                                                                                            \
    va_start(args, value);                                                                                \
    *value = (*env)->Call##_jname##MethodV(env, obj, methodID, args);                                        \
    if ((*env)->ExceptionCheck (env)) {                                                                      \
      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                               \
          "Failed to call Java method");                                                                \
      ret = FALSE;                                                                                           \
    }                                                                                                        \
    va_end(args);                                                                                            \
    return ret;                                                                                              \
  }

CALL_TYPE_METHOD (gboolean, boolean, Boolean);
CALL_TYPE_METHOD (gint8, byte, Byte);
CALL_TYPE_METHOD (gshort, short, Short);
CALL_TYPE_METHOD (gint, int, Int);
CALL_TYPE_METHOD (gchar, char, Char);
CALL_TYPE_METHOD (gint64, long, Long);
CALL_TYPE_METHOD (gfloat, float, Float);
CALL_TYPE_METHOD (gdouble, double, Double);
CALL_TYPE_METHOD (jobject, object, Object);

gboolean
gst_amc_jni_call_void_method (JNIEnv * env, GError ** err, jobject obj,
    jmethodID methodID, ...)
{
  gboolean ret = TRUE;
  va_list args;
  va_start (args, methodID);

  (*env)->CallVoidMethodV (env, obj, methodID, args);
  if ((*env)->ExceptionCheck (env)) {
    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
        GST_LIBRARY_ERROR_FAILED, "Failed to call Java method");
    ret = FALSE;
  }
  va_end (args);
  return ret;
}

#define GET_TYPE_FIELD(_type, _name, _jname)                                               \
gboolean gst_amc_jni_get_##_name##_field (JNIEnv *env, GError ** err, jobject obj, jfieldID fieldID, _type *value)   \
  {                                                                                                 \
    gboolean ret = TRUE;                                                                            \
                                                                                                    \
    *value = (*env)->Get##_jname##Field(env, obj, fieldID);                                         \
    if ((*env)->ExceptionCheck (env)) {                                                             \
      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                      \
          "Failed to get Java field");                                                         \
      ret = FALSE;                                                                                  \
    }                                                                                               \
    return ret;                                                                                     \
  }

GET_TYPE_FIELD (gboolean, boolean, Boolean);
GET_TYPE_FIELD (gint8, byte, Byte);
GET_TYPE_FIELD (gshort, short, Short);
GET_TYPE_FIELD (gint, int, Int);
GET_TYPE_FIELD (gchar, char, Char);
GET_TYPE_FIELD (gint64, long, Long);
GET_TYPE_FIELD (gfloat, float, Float);
GET_TYPE_FIELD (gdouble, double, Double);
GET_TYPE_FIELD (jobject, object, Object);

#define GET_STATIC_TYPE_FIELD(_type, _name, _jname)                                               \
gboolean gst_amc_jni_get_static_##_name##_field (JNIEnv *env, GError ** err, jclass klass, jfieldID fieldID, _type *value)   \
  {                                                                                                 \
    gboolean ret = TRUE;                                                                            \
                                                                                                    \
    *value = (*env)->GetStatic##_jname##Field(env, klass, fieldID);                                 \
    if ((*env)->ExceptionCheck (env)) {                                                             \
      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                      \
          "Failed to get static Java field");                                                  \
      ret = FALSE;                                                                                  \
    }                                                                                               \
    return ret;                                                                                     \
  }

GET_STATIC_TYPE_FIELD (gboolean, boolean, Boolean);
GET_STATIC_TYPE_FIELD (gint8, byte, Byte);
GET_STATIC_TYPE_FIELD (gshort, short, Short);
GET_STATIC_TYPE_FIELD (gint, int, Int);
GET_STATIC_TYPE_FIELD (gchar, char, Char);
GET_STATIC_TYPE_FIELD (gint64, long, Long);
GET_STATIC_TYPE_FIELD (gfloat, float, Float);
GET_STATIC_TYPE_FIELD (gdouble, double, Double);
GET_STATIC_TYPE_FIELD (jobject, object, Object);

gboolean
gst_amc_jni_get_buffer_array (JNIEnv * env, GError ** err, jobject array,
    GstAmcBuffer ** buffers, gsize * n_buffers)
{
  jsize i;

  *n_buffers = (*env)->GetArrayLength (env, array);
  *buffers = g_new0 (GstAmcBuffer, *n_buffers);

  for (i = 0; i < *n_buffers; i++) {
    jobject buffer = NULL;

    buffer = (*env)->GetObjectArrayElement (env, array, i);
    if ((*env)->ExceptionCheck (env) || !buffer) {
      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
          GST_LIBRARY_ERROR_FAILED, "Failed to get buffer %d", i);
      goto error;
    }

    (*buffers)[i].object = gst_amc_jni_object_make_global (env, buffer);
    if (!(*buffers)[i].object) {
      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
          GST_LIBRARY_ERROR_FAILED,
          "Failed to create global buffer reference %d", i);
      goto error;
    }

    (*buffers)[i].data =
        (*env)->GetDirectBufferAddress (env, (*buffers)[i].object);
    if (!(*buffers)[i].data) {
      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
          GST_LIBRARY_ERROR_FAILED, "Failed to get buffer address %d", i);
      goto error;
    }
    (*buffers)[i].size =
        (*env)->GetDirectBufferCapacity (env, (*buffers)[i].object);
  }

  return TRUE;

error:
  if (*buffers)
    gst_amc_jni_free_buffer_array (env, *buffers, *n_buffers);
  *buffers = NULL;
  *n_buffers = 0;
  return FALSE;
}

void
gst_amc_jni_free_buffer_array (JNIEnv * env, GstAmcBuffer * buffers,
    gsize n_buffers)
{
  jsize i;

  g_return_if_fail (buffers != NULL);

  for (i = 0; i < n_buffers; i++) {
    if (buffers[i].object)
      gst_amc_jni_object_unref (env, buffers[i].object);
  }
  g_free (buffers);
}

void
gst_amc_buffer_free (GstAmcBuffer * buffer)
{
  JNIEnv *env;

  g_return_if_fail (buffer != NULL);

  env = gst_amc_jni_get_env ();

  if (buffer->object)
    gst_amc_jni_object_unref (env, buffer->object);
  g_free (buffer);
}

GstAmcBuffer *
gst_amc_buffer_copy (GstAmcBuffer * buffer)
{
  JNIEnv *env;
  GstAmcBuffer *ret;

  g_return_val_if_fail (buffer != NULL, NULL);

  env = gst_amc_jni_get_env ();

  ret = g_new0 (GstAmcBuffer, 1);

  ret->object = gst_amc_jni_object_ref (env, buffer->object);
  ret->data = buffer->data;
  ret->size = buffer->size;

  return ret;
}

gboolean
gst_amc_buffer_get_position_and_limit (GstAmcBuffer * buffer, GError ** err,
    gint * position, gint * limit)
{
  JNIEnv *env;

  g_return_val_if_fail (buffer != NULL, FALSE);
  g_return_val_if_fail (buffer->object != NULL, FALSE);

  env = gst_amc_jni_get_env ();

  if (!gst_amc_jni_call_int_method (env, err, buffer->object,
          java_nio_buffer.get_position, position))
    return FALSE;

  if (!gst_amc_jni_call_int_method (env, err, buffer->object,
          java_nio_buffer.get_limit, limit))
    return FALSE;

  return TRUE;
}

gboolean
gst_amc_buffer_set_position_and_limit (GstAmcBuffer * buffer, GError ** err,
    gint position, gint limit)
{
  JNIEnv *env;
  jobject tmp;

  g_return_val_if_fail (buffer != NULL, FALSE);
  g_return_val_if_fail (buffer->object != NULL, FALSE);

  env = gst_amc_jni_get_env ();

  if (!gst_amc_jni_call_object_method (env, err, buffer->object,
          java_nio_buffer.set_limit, &tmp, limit))
    return FALSE;

  gst_amc_jni_object_local_unref (env, tmp);

  if (!gst_amc_jni_call_object_method (env, err, buffer->object,
          java_nio_buffer.set_position, &tmp, position))
    return FALSE;

  gst_amc_jni_object_local_unref (env, tmp);

  return TRUE;
}

gboolean
gst_amc_buffer_clear (GstAmcBuffer * buffer, GError ** err)
{
  JNIEnv *env;
  jobject tmp;

  g_return_val_if_fail (buffer != NULL, FALSE);
  g_return_val_if_fail (buffer->object != NULL, FALSE);

  env = gst_amc_jni_get_env ();

  if (!gst_amc_jni_call_object_method (env, err, buffer->object,
          java_nio_buffer.clear, &tmp))
    return FALSE;

  gst_amc_jni_object_local_unref (env, tmp);

  return TRUE;
}
