// 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.Options class.
	jOptionsClass Class
	// 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.Boolean class.
	jBooleanClass Class
	// Global reference for java.lang.Integer class.
	jIntegerClass 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
	jOptionsClass, err = JFindClass(env, "io/v/v23/Options")
	if err != nil {
		return err
	}
	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
	}
	jBooleanClass, err = JFindClass(env, "java/lang/Boolean")
	if err != nil {
		return err
	}
	jIntegerClass, err = JFindClass(env, "java/lang/Integer")
	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)))
	// 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 {
	jException := Object(uintptr(unsafe.Pointer(C.ExceptionOccurred(env.value()))))
	if jException.IsNull() { // no exception
		return nil
	}
	C.ExceptionClear(env.value())
	return GoError(env, jException)
}

// GoError converts the provided Java Exception into a Go error, converting VException into
// verror.T and all other exceptions into a Go error.
func GoError(env Env, jException Object) error {
	if jException.IsNull() {
		return nil
	}
	if IsInstanceOf(env, jException, 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, jException, 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, jException, "getMessage", nil, StringSign)
	if err != nil {
		return fmt.Errorf("error converting exception: " + err.Error())
	}
	defer freeFunc()
	strObj := C.CallObjectMethodA(env.value(), jException.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
}