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

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