// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build java android

// Package util provides various JNI utilities shared across our JNI code.
package util

import (
	"errors"
	"fmt"
	"log"
	"runtime"
	"time"
	"unicode"
	"unicode/utf8"
	"unsafe"

	"v.io/v23/vdl"
	"v.io/v23/vom"
)

// #include <stdlib.h>
// #include "jni_wrapper.h"
// static jstring CallGetExceptionMessage(JNIEnv* env, jobject obj, jmethodID id) {
//   return (jstring)(*env)->CallObjectMethod(env, obj, id);
// }
import "C"

type skipOptionType struct{}

var (
	// Global reference for io.v.v23.vom.VomUtil class.
	jVomUtilClass Class
	// Global reference for io.v.v23.verror.VException class.
	jVExceptionClass Class
	// Global reference for io.v.v23.verror.VException$ActionCode class.
	jActionCodeClass Class
	// Global reference for io.v.v23.verror.VException$IDAction class.
	jIDActionClass Class
	// Global reference for io.v.v23.vdl.VdlValue class.
	jVdlValueClass Class
	// Global reference for io.v.v23.vdl.VdlTypeObject class.
	jVdlTypeObjectClass Class
	// Global reference for org.joda.time.DateTime class.
	jDateTimeClass Class
	// Global reference for org.joda.time.Duration class.
	jDurationClass Class
	// Global reference for java.util.Arrays class
	jArraysClass Class
	// Global reference for java.util.ArrayList class.
	jArrayListClass Class
	// Global reference for java.lang.Throwable class.
	jThrowableClass Class
	// Global reference for java.lang.System class.
	jSystemClass Class
	// Global reference for java.lang.Object class.
	jObjectClass Class
	// Global reference for java.lang.String class.
	jStringClass Class
	// Global reference for java.util.HashMap class.
	jHashMapClass Class
	// Global reference for com.google.common.collect.HashMultimap class.
	jHashMultimapClass Class
	// Global reference for []byte class.
	jByteArrayClass Class
	// Cached Java VM.
	jVM *C.JavaVM

	// SkipOption is a special error that should be returned by the option
	// processing function passed to GoOptions. It indicates that the
	// option being processed should be skipped.
	SkipOption = skipOptionType{}
)

func (skipOptionType) Error() string {
	return "ignored option"
}

// Init initializes the JNI code with the given Java environment.  This method
// must be invoked before any other method in this package and must be called
// from the main Java thread (e.g., On_Load()).
func Init(env Env) error {
	var err error
	jVomUtilClass, err = JFindClass(env, "io/v/v23/vom/VomUtil")
	if err != nil {
		return err
	}
	jVExceptionClass, err = JFindClass(env, "io/v/v23/verror/VException")
	if err != nil {
		return err
	}
	jActionCodeClass, err = JFindClass(env, "io/v/v23/verror/VException$ActionCode")
	if err != nil {
		return err
	}
	jIDActionClass, err = JFindClass(env, "io/v/v23/verror/VException$IDAction")
	if err != nil {
		return err
	}
	jVdlValueClass, err = JFindClass(env, "io/v/v23/vdl/VdlValue")
	if err != nil {
		return err
	}
	jVdlTypeObjectClass, err = JFindClass(env, "io/v/v23/vdl/VdlTypeObject")
	if err != nil {
		return err
	}
	jDateTimeClass, err = JFindClass(env, "org/joda/time/DateTime")
	if err != nil {
		return err
	}
	jDurationClass, err = JFindClass(env, "org/joda/time/Duration")
	if err != nil {
		return err
	}
	jArraysClass, err = JFindClass(env, "java/util/Arrays")
	if err != nil {
		return err
	}
	jArrayListClass, err = JFindClass(env, "java/util/ArrayList")
	if err != nil {
		return err
	}
	jThrowableClass, err = JFindClass(env, "java/lang/Throwable")
	if err != nil {
		return err
	}
	jSystemClass, err = JFindClass(env, "java/lang/System")
	if err != nil {
		return err
	}
	jObjectClass, err = JFindClass(env, "java/lang/Object")
	if err != nil {
		return err
	}
	jStringClass, err = JFindClass(env, "java/lang/String")
	if err != nil {
		return err
	}
	jHashMapClass, err = JFindClass(env, "java/util/HashMap")
	if err != nil {
		return err
	}
	jHashMultimapClass, err = JFindClass(env, "com/google/common/collect/HashMultimap")
	if err != nil {
		return err
	}
	jByteArrayClass, err = JFindClass(env, "[B")
	if err != nil {
		return err
	}
	if status := C.GetJavaVM(env.value(), &jVM); status != 0 {
		return fmt.Errorf("couldn't get Java VM from the (Java) environment")
	}
	return nil
}

// CamelCase converts ThisString to thisString.
func CamelCase(s string) string {
	if s == "" {
		return ""
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToLower(r)) + s[n:]
}

// UpperCamelCase converts thisString to ThisString.
func UpperCamelCase(s string) string {
	if s == "" {
		return ""
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToUpper(r)) + s[n:]
}

// GoString returns a Go string given the Java string.
func GoString(env Env, str Object) string {
	if str.IsNull() {
		return ""
	}
	cString := C.GetStringUTFChars(env.value(), C.jstring(str.value()), nil)
	defer C.ReleaseStringUTFChars(env.value(), C.jstring(str.value()), cString)
	return C.GoString(cString)
}

// GetClass returns the class of the given object.
func GetClass(env Env, obj Object) Class {
	return Class(uintptr(unsafe.Pointer(C.GetObjectClass(env.value(), obj.value()))))
}

var envRefs = newSafeRefCounter()

// GetEnv returns the Java environment for the running thread, creating a new
// one if it doesn't already exist.  This method also returns a function which
// must be invoked when the returned environment is no longer needed. The
// returned environment can only be used by the thread that invoked this method,
// and the function must be invoked by the same thread as well.
func GetEnv() (env Env, free func()) {
	// Lock the goroutine to the current OS thread.  This is necessary as
	// *C.JNIEnv must not be shared across threads.  The scenario that can break
	// this requrement is:
	//   - goroutine A executing on thread X, obtaining a *C.JNIEnv pointer P.
	//   - goroutine A gets re-scheduled on thread Y, maintaining the pointer P.
	//   - goroutine B starts executing on thread X, obtaining pointer P.
	//
	// By locking the goroutines to their OS thread while they hold the pointer
	// to *C.JNIEnv, the above scenario can never occur.
	runtime.LockOSThread()
	var jenv *C.JNIEnv
	if C.GetEnv(jVM, &jenv, C.JNI_VERSION_1_6) != C.JNI_OK {
		// Couldn't get env - attach the thread.  Note that we never detach
		// the thread so the next call to GetEnv on this thread will succeed.
		C.AttachCurrentThreadAsDaemon(jVM, &jenv, nil)
	}
	env = Env(uintptr(unsafe.Pointer(jenv)))
	//env := Env{jenv}
	// GetEnv is called by Go code that wishes to call Java methods. In
	// this case, JNI cannot automatically free unused local refererences.
	// We must do it manually by pushing a new local reference frame. The
	// frame will be popped in the env's cleanup function below, at which
	// point JNI will free the unused references.
	// http://developer.android.com/training/articles/perf-jni.html states
	// that the JNI implementation is only required to provide a local
	// reference table with a capacity of 16, so here we provide a table of
	// that size.
	localRefCapacity := 16
	if newCapacity := PushLocalFrame(env, localRefCapacity); newCapacity < 0 {
		panic("PushLocalFrame(" + string(localRefCapacity) + ") returned < 0 (was " + string(newCapacity) + ")")
	}
	// Reference-count *env.  This is necessary to make GetEnv() re-entrant:
	// same goroutine should be allowed to call GetEnv() multiple times and
	// the OS thread should only be released after the last call to the free
	// function.
	envRefs.ref(jenv)
	return env, func() {
		PopLocalFrame(env, NullObject)
		if envRefs.unref(jenv) == 0 {
			// Last call to free the env out of possibly many successive
			// GetEnv() calls by the same goroutine: it is now safe to release
			// the thread.
			runtime.UnlockOSThread()
		}
	}
}

// IsInstanceOf returns true iff the provided Java object is an instance of the
// provided Java class.
func IsInstanceOf(env Env, obj Object, class Class) bool {
	return C.IsInstanceOf(env.value(), obj.value(), class.value()) == C.JNI_TRUE
}

// JString returns a Java string given the Go string.
func JString(env Env, str string) Object {
	cString := C.CString(str)
	defer C.free(unsafe.Pointer(cString))
	return Object(uintptr(unsafe.Pointer(C.NewStringUTF(env.value(), cString))))
}

// JThrow throws a new Java exception of the provided type with the given message.
func JThrow(env Env, class Class, msg string) {
	s := C.CString(msg)
	defer C.free(unsafe.Pointer(s))
	C.ThrowNew(env.value(), class.value(), s)
}

// JThrowV throws a new Java VException corresponding to the given error.
func JThrowV(env Env, err error) {
	if err == nil {
		log.Printf("Couldn't throw exception: nil error")
		return
	}
	obj, e := JVomCopy(env, err, jVExceptionClass)
	if e != nil {
		log.Printf("Couldn't throw exception %q: %v", err, e)
		return
	}
	C.Throw(env.value(), C.jthrowable(obj.value()))
}

// JVException returns the Java VException given the Go error.
func JVException(env Env, err error) (Object, error) {
	if err == nil {
		return NullObject, nil
	}
	return JVomCopy(env, err, jVExceptionClass)
}

// JExceptionMsg returns the exception message as a Go error, if an exception
// occurred, or nil otherwise.
func JExceptionMsg(env Env) error {
	eObj := Object(uintptr(unsafe.Pointer(C.ExceptionOccurred(env.value()))))
	if eObj.IsNull() { // no exception
		return nil
	}
	C.ExceptionClear(env.value())

	if IsInstanceOf(env, eObj, jVExceptionClass) {
		// VException: convert it into a verror.
		// Note that we can't use CallStaticObjectMethod below as it may lead to
		// an infinite loop.
		jmid, jArgArr, freeFunc, err := setupStaticMethodCall(env, jVomUtilClass, "encode", []Sign{ObjectSign, TypeSign}, ByteArraySign, eObj, jVExceptionClass)
		if err != nil {
			return fmt.Errorf("error converting VException: " + err.Error())
		}
		defer freeFunc()
		dataObj := C.CallStaticObjectMethodA(env.value(), jVomUtilClass.value(), jmid, jArgArr)
		if e := C.ExceptionOccurred(env.value()); e != nil {
			C.ExceptionClear(env.value())
			return fmt.Errorf("error converting VException: exception during VomUtil.encode()")
		}
		data := GoByteArray(env, Object(uintptr(unsafe.Pointer(dataObj))))
		var verr error
		if err := vom.Decode(data, &verr); err != nil {
			return fmt.Errorf("error converting VException: " + err.Error())
		}
		return verr
	}
	// Not a VException: convert it into a Go error.
	// Note that we can't use CallObjectMethod below, as it may lead to an
	// infinite loop.
	jmid, jArgArr, freeFunc, err := setupMethodCall(env, eObj, "getMessage", nil, StringSign)
	if err != nil {
		return fmt.Errorf("error converting exception: " + err.Error())
	}
	defer freeFunc()
	strObj := C.CallObjectMethodA(env.value(), eObj.value(), jmid, jArgArr)
	if e := C.ExceptionOccurred(env.value()); e != nil {
		C.ExceptionClear(env.value())
		return fmt.Errorf("error converting exception: exception during Throwable.getMessage()")
	}
	return errors.New(GoString(env, Object(uintptr(unsafe.Pointer(strObj)))))
}

// JObjectField returns the value of the provided Java object's Object field, or
// error if the field value couldn't be retrieved.
func JObjectField(env Env, obj Object, field string, sign Sign) (Object, error) {
	fid, err := jFieldID(env, GetClass(env, obj), field, sign)
	if err != nil {
		return NullObject, err
	}
	return Object(uintptr(unsafe.Pointer(C.GetObjectField(env.value(), obj.value(), fid)))), nil
}

// JBoolField returns the value of the provided Java object's boolean field, or
// error if the field value couldn't be retrieved.
func JBoolField(env Env, obj Object, field string) (bool, error) {
	fid, err := jFieldID(env, GetClass(env, obj), field, BoolSign)
	if err != nil {
		return false, err
	}
	return C.GetBooleanField(env.value(), obj.value(), fid) != C.JNI_FALSE, nil
}

// JIntField returns the value of the provided Java object's int field, or
// error if the field value couldn't be retrieved.
func JIntField(env Env, obj Object, field string) (int, error) {
	fid, err := jFieldID(env, GetClass(env, obj), field, IntSign)
	if err != nil {
		return -1, err
	}
	return int(C.GetIntField(env.value(), obj.value(), fid)), nil
}

// JLongField returns the value of the provided Java object's long field, or
// error if the field value couldn't be retrieved.
func JLongField(env Env, obj Object, field string) (int64, error) {
	fid, err := jFieldID(env, GetClass(env, obj), field, LongSign)
	if err != nil {
		return -1, err
	}
	return int64(C.GetLongField(env.value(), obj.value(), fid)), nil
}

// JStringField returns the value of the provided Java object's String field, or
// error if the field value couldn't be retrieved.
func JStringField(env Env, obj Object, field string) (string, error) {
	strObj, err := JObjectField(env, obj, field, StringSign)
	if err != nil {
		return "", err
	}
	return GoString(env, strObj), nil
}

// JStringArrayField returns the value of the provided object's String[] field,
// or error if the field value couldn't be retrieved.
func JStringArrayField(env Env, obj Object, field string) ([]string, error) {
	arrObj, err := JObjectField(env, obj, field, ArraySign(StringSign))
	if err != nil {
		return nil, err
	}
	return GoStringArray(env, arrObj)
}

// JByteArrayField returns the value of the provided object's byte[] field, or
// error if the field value couldn't be retrieved.
func JByteArrayField(env Env, obj Object, field string) ([]byte, error) {
	arrObj, err := JObjectField(env, obj, field, ArraySign(ByteSign))
	if err != nil {
		return nil, err
	}
	return GoByteArray(env, arrObj), nil
}

// JByteArrayArrayField returns the value of the provided object's byte[][]
// field, or error if the field value couldn't be retrieved.
func JByteArrayArrayField(env Env, obj Object, field string) ([][]byte, error) {
	arrObj, err := JObjectField(env, obj, field, ArraySign(ArraySign(ByteSign)))
	if err != nil {
		return nil, err
	}
	return GoByteArrayArray(env, arrObj)
}

func JStaticObjectField(env Env, class Class, field string, sign Sign) (Object, error) {
	fid, err := jStaticFieldID(env, class, field, sign)
	if err != nil {
		return NullObject, err
	}
	return Object(uintptr(unsafe.Pointer(C.GetStaticObjectField(env.value(), class.value(), fid)))), nil
}

// JStaticStringField returns the value of the static String field of the
// provided Java class, or error if the field value couldn't be retrieved.
func JStaticStringField(env Env, class Class, field string) (string, error) {
	strObj, err := JStaticObjectField(env, class, field, StringSign)
	if err != nil {
		return "", err
	}
	return GoString(env, strObj), nil
}

// JObjectArray converts the provided slice of objects into a Java object
// array of the provided element type.
func JObjectArray(env Env, arr []Object, elemClass Class) (Object, error) {
	arrObj := C.NewObjectArray(env.value(), C.jsize(len(arr)), elemClass.value(), nil)
	for i, elem := range arr {
		C.SetObjectArrayElement(env.value(), arrObj, C.jsize(i), elem.value())
		if err := JExceptionMsg(env); err != nil {
			return NullObject, err
		}
	}
	return Object(uintptr(unsafe.Pointer(arrObj))), nil
}

// GoObjectArray converts a Java object array to a Go slice of Java objects.
func GoObjectArray(env Env, arr Object) ([]Object, error) {
	if arr.IsNull() {
		return nil, nil
	}
	length := int(C.GetArrayLength(env.value(), C.jarray(arr.value())))
	ret := make([]Object, length)
	for i := 0; i < length; i++ {
		ret[i] = Object(uintptr(unsafe.Pointer(C.GetObjectArrayElement(env.value(), C.jobjectArray(arr.value()), C.jsize(i)))))
		if err := JExceptionMsg(env); err != nil {
			// Out-of-bounds index.
			return nil, err
		}
	}
	return ret, nil
}

// JObjectList converts the provided slice of Java objects into a Java List
// of the provided element type.
func JObjectList(env Env, arr []Object, elemClass Class) (Object, error) {
	arrObj, err := JObjectArray(env, arr, elemClass)
	if err != nil {
		return NullObject, err
	}
	listObj, err := CallStaticObjectMethod(env, jArraysClass, "asList", []Sign{ArraySign(ObjectSign)}, ListSign, arrObj)
	if err != nil {
		return NullObject, err
	}
	return NewObject(env, jArrayListClass, []Sign{CollectionSign}, listObj)
}

// GoObjectList converts the provided Java list of objects into a Go slice
// of Java objects.
func GoObjectList(env Env, list Object) ([]Object, error) {
	if list.IsNull() {
		return nil, nil
	}
	arrObj, err := CallObjectMethod(env, list, "toArray", nil, ArraySign(ObjectSign))
	if err != nil {
		return nil, err
	}
	return GoObjectArray(env, arrObj)
}

// GoStringList converts the provided Java List<String> Strings into a Go slice of
// strings.
func GoStringList(env Env, list Object) ([]string, error) {
	if list.IsNull() {
		return nil, nil
	}
	strArr, err := GoObjectList(env, list)
	if err != nil {
		return nil, err
	}
	ret := make([]string, len(strArr))
	for i, strObj := range strArr {
		ret[i] = GoString(env, strObj)
	}
	return ret, nil
}

// JStringArray converts the provided slice of Go strings into a Java array of
// strings.
func JStringArray(env Env, strs []string) (Object, error) {
	strArr := make([]Object, len(strs))
	for i, str := range strs {
		strArr[i] = JString(env, str)
	}
	return JObjectArray(env, strArr, jStringClass)
}

// GoStringArray converts a Java string array to a Go string slice.
func GoStringArray(env Env, arr Object) ([]string, error) {
	if arr.IsNull() {
		return nil, nil
	}
	strArr, err := GoObjectArray(env, arr)
	if err != nil {
		return nil, err
	}
	ret := make([]string, len(strArr))
	for i, strObj := range strArr {
		ret[i] = GoString(env, strObj)
	}
	return ret, nil
}

// JByteArray converts the provided Go byte slice into a Java byte array.
func JByteArray(env Env, bytes []byte) (Object, error) {
	arr := C.NewByteArray(env.value(), C.jsize(len(bytes)))
	if len(bytes) > 0 {
		C.SetByteArrayRegion(env.value(), arr, 0, C.jsize(len(bytes)), (*C.jbyte)(unsafe.Pointer(&bytes[0])))
		if err := JExceptionMsg(env); err != nil {
			return NullObject, err
		}
	}
	return Object(uintptr(unsafe.Pointer(arr))), nil
}

// GoByteArray converts the provided Java byte array into a Go byte slice.
func GoByteArray(env Env, arr Object) (ret []byte) {
	if arr.IsNull() {
		return nil
	}
	length := int(C.GetArrayLength(env.value(), C.jarray(arr.value())))
	ret = make([]byte, length)
	bytes := C.GetByteArrayElements(env.value(), C.jbyteArray(arr.value()), nil)
	defer C.ReleaseByteArrayElements(env.value(), C.jbyteArray(arr.value()), bytes, C.JNI_ABORT)
	ptr := bytes
	for i := 0; i < length; i++ {
		ret[i] = byte(*ptr)
		ptr = (*C.jbyte)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) + unsafe.Sizeof(*ptr)))
	}
	return
}

// GoLongArray converts the provided Java long array into a Go int64 slice.
func GoLongArray(env Env, arr Object) (ret []int64) {
	if arr.IsNull() {
		return
	}
	length := int(C.GetArrayLength(env.value(), C.jarray(arr.value())))
	ret = make([]int64, length)
	elems := C.GetLongArrayElements(env.value(), C.jlongArray(arr.value()), nil)
	defer C.ReleaseLongArrayElements(env.value(), C.jlongArray(arr.value()), elems, C.JNI_ABORT)
	ptr := elems
	for i := 0; i < length; i++ {
		ret[i] = int64(*ptr)
		ptr = (*C.jlong)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) + unsafe.Sizeof(*ptr)))
	}
	return
}

// JByteArrayArray converts the provided [][]byte value into a Java array of
// byte arrays.
func JByteArrayArray(env Env, arr [][]byte) (Object, error) {
	objArr := make([]Object, len(arr))
	for i, elem := range arr {
		var err error
		if objArr[i], err = JByteArray(env, elem); err != nil {
			return NullObject, err
		}
	}
	return JObjectArray(env, objArr, jByteArrayClass)
}

// GoByteArrayArray converts the provided Java array of byte arrays into a Go
// [][]byte value.
func GoByteArrayArray(env Env, arr Object) ([][]byte, error) {
	objArr, err := GoObjectArray(env, arr)
	if err != nil {
		return nil, err
	}
	ret := make([][]byte, len(objArr))
	for i, obj := range objArr {
		ret[i] = GoByteArray(env, obj)
	}
	return ret, nil
}

// JVDLValueArray converts the provided Go slice of *vdl.Value values into a
// Java array of VdlValue objects.
func JVDLValueArray(env Env, arr []*vdl.Value) (Object, error) {
	objArr := make([]Object, len(arr))
	for i, val := range arr {
		var err error
		if objArr[i], err = JVomCopy(env, val, jVdlValueClass); err != nil {
			return NullObject, err
		}
	}
	return JObjectArray(env, objArr, jVdlValueClass)
}

// GoVDLValueArray converts the provided Java array of VdlValue objects into a
// Go slice of *vdl.Value values.
func GoVDLValueArray(env Env, arr Object) ([]*vdl.Value, error) {
	objArr, err := GoObjectArray(env, arr)
	if err != nil {
		return nil, err
	}
	vals := make([]*vdl.Value, len(objArr))
	for i, obj := range objArr {
		var err error
		if vals[i], err = GoVomCopyValue(env, obj); err != nil {
			return nil, err
		}
	}
	return vals, nil
}

// JObjectMap converts the provided Go map of Java objects into a Java
// object map.
func JObjectMap(env Env, m map[Object]Object) (Object, error) {
	mapObj, err := NewObject(env, jHashMapClass, nil)
	if err != nil {
		return NullObject, err
	}
	for keyObj, valObj := range m {
		if _, err := CallObjectMethod(env, mapObj, "put", []Sign{ObjectSign, ObjectSign}, ObjectSign, keyObj, valObj); err != nil {
			return NullObject, err
		}
	}
	return mapObj, nil
}

// GoObjectMap converts the provided Java object map into a Go map of Java
// objects.
func GoObjectMap(env Env, mapObj Object) (map[Object]Object, error) {
	if mapObj.IsNull() {
		return nil, nil
	}
	keysObj, err := CallObjectMethod(env, mapObj, "keySet", nil, SetSign)
	if err != nil {
		return nil, err
	}
	keysArr, err := CallObjectArrayMethod(env, keysObj, "toArray", nil, ObjectSign)
	if err != nil {
		return nil, err
	}
	ret := make(map[Object]Object)
	for _, keyObj := range keysArr {
		valObj, err := CallObjectMethod(env, mapObj, "get", []Sign{ObjectSign}, ObjectSign, keyObj)
		if err != nil {
			return nil, err
		}
		ret[keyObj] = valObj
	}
	return ret, nil
}

// JObjectMultimap converts the provided Go map of Java objects into a Java
// object multimap.
func JObjectMultimap(env Env, goMap map[Object][]Object) (Object, error) {
	mapObj, err := NewObject(env, jHashMultimapClass, nil)
	if err != nil {
		return NullObject, err
	}
	for keyObj, vals := range goMap {
		for _, valObj := range vals {
			if _, err := CallBooleanMethod(env, mapObj, "put", []Sign{ObjectSign, ObjectSign}, keyObj, valObj); err != nil {
				return NullObject, err
			}
		}
	}
	return mapObj, nil
}

// GoObjectMultimap converts the provided Java Multimap object into a Go map
// of Java objects.
func GoObjectMultimap(env Env, multiMap Object) (map[Object][]Object, error) {
	if multiMap.IsNull() {
		return nil, nil
	}
	keysObj, err := CallObjectMethod(env, multiMap, "keySet", nil, SetSign)
	if err != nil {
		return nil, err
	}
	keysArr, err := CallObjectArrayMethod(env, keysObj, "toArray", nil, ObjectSign)
	if err != nil {
		return nil, err
	}
	ret := make(map[Object][]Object)
	for _, keyObj := range keysArr {
		valsObj, err := CallObjectMethod(env, multiMap, "get", []Sign{ObjectSign}, CollectionSign, keyObj)
		if err != nil {
			return nil, err
		}
		valsArr, err := CallObjectArrayMethod(env, valsObj, "toArray", nil, ObjectSign)
		if err != nil {
			return nil, err
		}
		ret[keyObj] = valsArr
	}
	return ret, nil
}

// JFindClass returns the global reference to the Java class with the
// given pathname, or an error if the class cannot be found.
func JFindClass(env Env, name string) (Class, error) {
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))

	class := C.FindClass(env.value(), cName)
	if err := JExceptionMsg(env); err != nil || class == nil {
		return NullClass, fmt.Errorf("couldn't find class %s: %v", name, err)
	}
	obj := NewGlobalRef(env, Object(uintptr(unsafe.Pointer(class))))
	return Class(uintptr(unsafe.Pointer(C.jclass(obj.value())))), nil
}

// GoOptions converts a Java io.v.v23.Options instance into a slice of Go
// options (stored as interface{}).
//
// For each entry in the Java Option map, the user-supplied
// optionFunc is called to turn the entry into its corresponding Go option. It
// is up to the caller to cast the returned value to the appropriate Go type.
// If optionFunc returns a non-nil error, the err and a nil slice will be
// returned.
//
// The only exception to this rule is the special SkipOption error:
// if optionFunc returns this, the option will not be added to the result and
// option processing will continue.
func GoOptions(env Env, opts Object, optionFunc func(env Env, key string, opt Object) (interface{}, error)) ([]interface{}, error) {
	if opts.IsNull() {
		return []interface{}{}, nil
	}
	mapObj, err := CallMapMethod(env, opts, "asMap", []Sign{})
	if err != nil {
		return nil, err
	}
	var result []interface{}
	for keyObj, valObj := range mapObj {
		key := GoString(env, keyObj)
		value, err := optionFunc(env, key, valObj)
		if err == SkipOption {
			continue
		}
		if err != nil {
			return nil, err
		}
		result = append(result, value)
	}
	return result, nil
}

// JTime converts the provided Go time.Time value into a Java DateTime
// object.
func JTime(env Env, t time.Time) (Object, error) {
	millis := t.UnixNano() / 1000000
	return NewObject(env, jDateTimeClass, []Sign{LongSign}, millis)
}

// GoTime converts the provided Java DateTime object into a Go time.Time value.
func GoTime(env Env, timeObj Object) (time.Time, error) {
	if timeObj.IsNull() {
		return time.Time{}, nil
	}
	millis, err := CallLongMethod(env, timeObj, "getMillis", nil)
	if err != nil {
		return time.Time{}, err
	}
	sec := millis / 1000
	nsec := (millis % 1000) * 1000000
	return time.Unix(sec, nsec), nil
}

// JDuration converts the provided Go time.Duration value into a Java
// Duration object.
func JDuration(env Env, d time.Duration) (Object, error) {
	millis := d.Nanoseconds() / 1000000
	return NewObject(env, jDurationClass, []Sign{LongSign}, int64(millis))
}

// GoDuration converts the provided Java Duration object into a Go time.Duration
// value.
func GoDuration(env Env, duration Object) (time.Duration, error) {
	millis, err := CallLongMethod(env, duration, "getMillis", nil)
	if err != nil {
		return 0, err
	}
	return time.Duration(millis) * time.Millisecond, nil
}

// PushLocalFrame pushes a new local reference frame onto the reference frame
// stack. If the return value is >= 0, the new frame will have capacity for at
// least the specified number of local references. If the return value is < 0,
// the reference frame could not be created.
func PushLocalFrame(env Env, capacity int) int {
	return int(C.PushLocalFrame(env.value(), C.jint(capacity)))
}

// PopLocalFrame pops the most recent local reference frame off the reference
// frame stack. Returns a local reference in the previous reference frame to
// the given jFramePtr object. If you do not require a reference to the
// previous frame, you may pass nil for the jFramePtr parameter.
func PopLocalFrame(env Env, result Object) Object {
	if result.IsNull() {
		return Object(uintptr(unsafe.Pointer(C.PopLocalFrame(env.value(), nil))))
	}
	return Object(uintptr(unsafe.Pointer(C.PopLocalFrame(env.value(), result.value()))))
}

// jFieldID returns the Java field ID for the given object (i.e., non-static)
// field, or an error if the field couldn't be found.
func jFieldID(env Env, class Class, name string, sign Sign) (C.jfieldID, error) {
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))
	cSign := C.CString(string(sign))
	defer C.free(unsafe.Pointer(cSign))
	fid := C.GetFieldID(env.value(), class.value(), cName, cSign)
	if err := JExceptionMsg(env); err != nil || fid == nil {
		return nil, fmt.Errorf("couldn't find field %s: %v", name, err)
	}
	return fid, nil
}

// jStaticFieldID returns the Java field ID for the given static field,
// or an error if the field couldn't be found.
func jStaticFieldID(env Env, class Class, name string, sign Sign) (C.jfieldID, error) {
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))
	cSign := C.CString(string(sign))
	defer C.free(unsafe.Pointer(cSign))
	fid := C.GetStaticFieldID(env.value(), class.value(), cName, cSign)
	if err := JExceptionMsg(env); err != nil || fid == nil {
		return nil, fmt.Errorf("couldn't find field %s: %v", name, err)
	}
	return fid, nil
}

func callOnFailure(env Env, callback Object, err error) {
	if err := CallVoidMethod(env, callback, "onFailure", []Sign{VExceptionSign}, err); err != nil {
		panic(fmt.Sprintf("couldn't call Java onFailure method: %v", err))
	}
}

func callOnSuccess(env Env, callback Object, obj Object) {
	if err := CallVoidMethod(env, callback, "onSuccess", []Sign{ObjectSign}, obj); err != nil {
		panic(fmt.Sprintf("couldn't call Java onSuccess method: %v", err))
	}
}

// DoAsyncCall invokes the given fnToWrap in a goroutine. If fnToWrap returns an
// error, the given callback's onFailure method is invoked with the error as a
// parameter. If fnToWrap succeeds, its Object result is passed as a
// parameter to the callback's onSuccess method.
//
// The caller of doAsyncCall must take care that no local JNI references are
// used in fnToWrap's closure. For example:
//
// func myNativeCall(env Env, callback Object, someJObject C.jobject) {
//     doAsyncCallback(env, callback, func(env Env) (Object, error) {
//         callSomeMethodOn(someJObject)  // not OK, someJObject is a local JNI reference
//                                        // in the caller's scope.
//         ...
//     }
// }
//
// fnToWrap is run in on an arbitrary thread and local
// JNI references are only valid in the scope of a particular thread. You are
// free to capture any pure-Go variables and we recommend that you use that
// approach to pass parameters through to fnToWrap.
func DoAsyncCall(env Env, callback Object, fnToWrap func(env Env) (Object, error)) {
	go func(callback Object) {
		env, freeFunc := GetEnv()
		defer freeFunc()
		defer DeleteGlobalRef(env, callback)
		if result, err := fnToWrap(env); err != nil {
			callOnFailure(env, callback, err)
		} else {
			callOnSuccess(env, callback, result)
		}
	}(NewGlobalRef(env, callback))
}
