// 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"

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

// 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()).
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func Init(jEnv interface{}) error {
	env := getEnv(jEnv)
	class, err := JFindClass(env, "io/v/v23/vom/VomUtil")
	if err != nil {
		return err
	}
	jVomUtilClass = C.jclass(class)
	class, err = JFindClass(env, "io/v/v23/verror/VException")
	if err != nil {
		return err
	}
	jVExceptionClass = C.jclass(class)
	class, err = JFindClass(env, "io/v/v23/verror/VException$ActionCode")
	if err != nil {
		return err
	}
	jActionCodeClass = C.jclass(class)
	class, err = JFindClass(env, "io/v/v23/verror/VException$IDAction")
	if err != nil {
		return err
	}
	jIDActionClass = C.jclass(class)
	class, err = JFindClass(env, "io/v/v23/vdl/VdlValue")
	if err != nil {
		return err
	}
	jVdlValueClass = C.jclass(class)
	class, err = JFindClass(env, "org/joda/time/DateTime")
	if err != nil {
		return err
	}
	jDateTimeClass = C.jclass(class)
	class, err = JFindClass(env, "org/joda/time/Duration")
	if err != nil {
		return err
	}
	jDurationClass = C.jclass(class)
	class, err = JFindClass(env, "java/lang/Throwable")
	if err != nil {
		return err
	}
	jThrowableClass = C.jclass(class)
	class, err = JFindClass(env, "java/lang/System")
	if err != nil {
		return err
	}
	jSystemClass = C.jclass(class)
	class, err = JFindClass(env, "java/lang/Object")
	if err != nil {
		return err
	}
	jObjectClass = C.jclass(class)
	class, err = JFindClass(env, "java/lang/String")
	if err != nil {
		return err
	}
	jStringClass = C.jclass(class)
	class, err = JFindClass(env, "java/util/HashMap")
	if err != nil {
		return err
	}
	jHashMapClass = C.jclass(class)
	class, err = JFindClass(env, "com/google/common/collect/HashMultimap")
	if err != nil {
		return err
	}
	jHashMultimapClass = C.jclass(class)
	class, err = JFindClass(env, "[B")
	if err != nil {
		return err
	}
	jByteArrayClass = C.jclass(class)
	if status := C.GetJavaVM(env, &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.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoString(jEnv, jStr interface{}) string {
	env := getEnv(jEnv)
	str := getString(jStr)
	if str == nil {
		return ""
	}
	cString := C.GetStringUTFChars(env, str, nil)
	defer C.ReleaseStringUTFChars(env, str, cString)
	return C.GoString(cString)
}

// 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() (jEnv unsafe.Pointer, 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 env *C.JNIEnv
	if C.GetEnv(jVM, &env, C.JNI_VERSION_1_6) == C.JNI_OK {
		return unsafe.Pointer(env), func() {
			runtime.UnlockOSThread()
		}
	}
	// Couldn't get env, attach the thread.
	C.AttachCurrentThread(jVM, &env, nil)
	return unsafe.Pointer(env), func() {
		C.DetachCurrentThread(jVM)
		runtime.UnlockOSThread()
	}
}

// IsInstanceOf returns true iff the provided Java object is an instance of the
// provided Java class.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func IsInstanceOf(jEnv, jObj, jClass interface{}) bool {
	env := getEnv(jEnv)
	obj := getObject(jObj)
	class := getClass(jClass)
	return C.IsInstanceOf(env, obj, class) == C.JNI_TRUE
}

// IsJavaObject returns true iff the provided value is of type C.jobject.
// Note that this test is somewhat flawed: if the object is created by a package
// other than this one, the type will be C.jobject local to that package, which
// will fail the test below.  (This is because CGO creates package-local types.)
// So this test should be trusted only if we are sure that the passed-in object
// value would have been created by this package.
func IsJavaObject(value interface{}) bool {
	_, ok := value.(C.jobject)
	return ok
}

// JString returns a Java string given the Go string.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JString(jEnv interface{}, str string) unsafe.Pointer {
	env := getEnv(jEnv)
	cString := C.CString(str)
	defer C.free(unsafe.Pointer(cString))
	return unsafe.Pointer(C.NewStringUTF(env, cString))
}

// JThrow throws a new Java exception of the provided type with the given message.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JThrow(jEnv, jClass interface{}, msg string) {
	env := getEnv(jEnv)
	class := getClass(jClass)
	s := C.CString(msg)
	defer C.free(unsafe.Pointer(s))
	C.ThrowNew(env, class, s)
}

// JThrowV throws a new Java VException corresponding to the given error.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JThrowV(jEnv interface{}, err error) {
	jObj, errNew := JVException(jEnv, err)
	if errNew != nil {
		log.Printf("Couldn't throw exception %q: %v", err, errNew)
		return
	}
	if jObj == nil {
		log.Printf("Couldn't throw exception %q: got null Java exception", err)
		return
	}
	env := getEnv(jEnv)
	C.Throw(env, C.jthrowable(jObj))
}

// JVException returns the Java VException given the Go error.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JVException(jEnv interface{}, err error) (unsafe.Pointer, error) {
	if err == nil {
		return nil, nil
	}
	return JVomCopy(jEnv, err, jVExceptionClass)
}

// JExceptionMsg returns the exception message as a Go error, if an exception
// occurred, or nil otherwise.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JExceptionMsg(jEnv interface{}) error {
	env := getEnv(jEnv)
	e := C.ExceptionOccurred(env)
	if e == nil { // no exception
		return nil
	}
	C.ExceptionClear(env)
	if IsInstanceOf(jEnv, C.jobject(e), jVExceptionClass) {
		// VException: convert it into a verror.
		// Note that we can't use CallStaticObjectMethod below as it may lead to
		// an infinite loop.
		jenv, jclass, jmid, jValArray, freeFunc, err := setupStaticMethodCall(env, jVomUtilClass, "encode", []Sign{ObjectSign, TypeSign}, ByteArraySign, C.jobject(e), jVExceptionClass)
		if err != nil {
			return fmt.Errorf("error converting VException: " + err.Error())
		}
		defer freeFunc()
		jData := C.CallStaticObjectMethodA(jenv, jclass, jmid, jValArray)
		if e := C.ExceptionOccurred(env); e != nil {
			C.ExceptionClear(env)
			return fmt.Errorf("error converting VException: exception during VomUtil.encode()")
		}
		data := GoByteArray(env, jData)
		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.
	jenv, jobject, jmid, jValArray, freeFunc, err := setupMethodCall(env, C.jobject(e), "getMessage", nil, StringSign)
	if err != nil {
		return fmt.Errorf("error converting exception: " + err.Error())
	}
	defer freeFunc()
	jMsg := C.CallObjectMethodA(jenv, jobject, jmid, jValArray)
	if e := C.ExceptionOccurred(env); e != nil {
		C.ExceptionClear(env)
		return fmt.Errorf("error converting exception: exception during Throwable.getMessage()")
	}
	return errors.New(GoString(env, jMsg))
}

// JObjectField returns the value of the provided Java object's Object field, or
// error if the field value couldn't be retrieved.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JObjectField(jEnv, jObj interface{}, field string) (unsafe.Pointer, error) {
	env := getEnv(jEnv)
	obj := getObject(jObj)
	fid, err := JFieldIDPtr(env, C.GetObjectClass(env, obj), field, ObjectSign)
	if err != nil {
		return nil, err
	}
	return unsafe.Pointer(C.GetObjectField(env, obj, C.jfieldID(fid))), nil
}

// JBoolField returns the value of the provided Java object's boolean field, or
// error if the field value couldn't be retrieved.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JBoolField(jEnv, jObj interface{}, field string) (bool, error) {
	env := getEnv(jEnv)
	obj := getObject(jObj)
	fid, err := JFieldIDPtr(env, C.GetObjectClass(env, obj), field, BoolSign)
	if err != nil {
		return false, err
	}
	return C.GetBooleanField(env, obj, C.jfieldID(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.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JIntField(jEnv, jObj interface{}, field string) (int, error) {
	env := getEnv(jEnv)
	obj := getObject(jObj)
	fid, err := JFieldIDPtr(env, C.GetObjectClass(env, obj), field, IntSign)
	if err != nil {
		return -1, err
	}
	return int(C.GetIntField(env, obj, C.jfieldID(fid))), nil
}

// JStringField returns the value of the provided Java object's String field, or
// error if the field value couldn't be retrieved.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JStringField(jEnv, jObj interface{}, field string) (string, error) {
	env := getEnv(jEnv)
	obj := getObject(jObj)
	fid, err := JFieldIDPtr(env, C.GetObjectClass(env, obj), field, StringSign)
	if err != nil {
		return "", err
	}
	jStr := C.jstring(C.GetObjectField(env, obj, C.jfieldID(fid)))
	return GoString(env, jStr), nil
}

// JStringArrayField returns the value of the provided object's String[] field,
// or error if the field value couldn't be retrieved.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JStringArrayField(jEnv, jObj interface{}, field string) ([]string, error) {
	env := getEnv(jEnv)
	obj := getObject(jObj)
	fid, err := JFieldIDPtr(env, C.GetObjectClass(env, obj), field, ArraySign(StringSign))
	if err != nil {
		return nil, err
	}
	jStrArray := C.jobjectArray(C.GetObjectField(env, obj, C.jfieldID(fid)))
	return GoStringArray(env, jStrArray), nil
}

// JByteArrayField returns the value of the provided object's byte[] field, or
// error if the field value couldn't be retrieved.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JByteArrayField(jEnv, jObj interface{}, field string) ([]byte, error) {
	env := getEnv(jEnv)
	obj := getObject(jObj)
	fid, err := JFieldIDPtr(env, C.GetObjectClass(env, obj), field, ArraySign(ByteSign))
	if err != nil {
		return nil, err
	}
	arr := C.jbyteArray(C.GetObjectField(env, obj, C.jfieldID(fid)))
	if arr == nil {
		return nil, nil
	}
	return GoByteArray(env, arr), nil
}

// JByteArrayArrayField returns the value of the provided object's byte[][]
// field, or error if the field value couldn't be retrieved.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JByteArrayArrayField(jEnv, jObj interface{}, field string) ([][]byte, error) {
	env := getEnv(jEnv)
	obj := getObject(jObj)
	fid, err := JFieldIDPtr(env, C.GetObjectClass(env, obj), field, ArraySign(ArraySign(ByteSign)))
	if err != nil {
		return nil, err
	}
	arr := C.jobjectArray(C.GetObjectField(env, obj, C.jfieldID(fid)))
	if arr == nil {
		return nil, nil
	}
	return GoByteArrayArray(env, arr), nil
}

func JStaticObjectField(jEnv, jClass interface{}, field string, fieldTypeSign Sign) (C.jobject, error) {
	env := getEnv(jEnv)
	class := getClass(jClass)
	fid, err := JStaticFieldIDPtr(env, class, field, fieldTypeSign)
	if err != nil {
		return nil, err
	}
	return C.jobject(C.GetStaticObjectField(env, class, C.jfieldID(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.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JStaticStringField(jEnv, jClass interface{}, field string) (string, error) {
	env := getEnv(jEnv)
	class := getClass(jClass)
	fid, err := JStaticFieldIDPtr(env, class, field, StringSign)
	if err != nil {
		return "", err
	}
	jStr := C.jstring(C.GetStaticObjectField(env, class, C.jfieldID(fid)))
	return GoString(env, jStr), nil
}

// JObjectArray converts the provided slice of C.jobject pointers into a Java
// array of the provided element type.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JObjectArray(jEnv interface{}, arr []interface{}, jElemClass interface{}) unsafe.Pointer {
	if arr == nil {
		return nil
	}
	env := getEnv(jEnv)
	jElementClass := getClass(jElemClass)
	ret := C.NewObjectArray(env, C.jsize(len(arr)), jElementClass, nil)
	for i, elem := range arr {
		jElem := getObject(elem)
		C.SetObjectArrayElement(env, ret, C.jsize(i), jElem)
	}
	return unsafe.Pointer(ret)
}

// GoObjectArray converts a Java Object array to a Go slice of C.jobject
// pointers.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoObjectArray(jEnv, jObjArray interface{}) []unsafe.Pointer {
	env := getEnv(jEnv)
	jArr := getObjectArray(jObjArray)
	if jArr == nil {
		return nil
	}
	length := C.GetArrayLength(env, C.jarray(jArr))
	ret := make([]unsafe.Pointer, int(length))
	for i := 0; i < int(length); i++ {
		ret[i] = unsafe.Pointer(C.GetObjectArrayElement(env, jArr, C.jsize(i)))
	}
	return ret
}

// JStringArray converts the provided slice of Go strings into a Java array of
// strings.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JStringArray(jEnv interface{}, strs []string) unsafe.Pointer {
	if strs == nil {
		return nil
	}
	env := getEnv(jEnv)
	ret := C.NewObjectArray(env, C.jsize(len(strs)), jStringClass, nil)
	for i, str := range strs {
		C.SetObjectArrayElement(env, ret, C.jsize(i), C.jobject(JString(env, str)))
	}
	return unsafe.Pointer(ret)
}

// GoStringArray converts a Java string array to a Go string array.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoStringArray(jEnv, jStrArray interface{}) []string {
	env := getEnv(jEnv)
	jArr := getObjectArray(jStrArray)
	if jArr == nil {
		return nil
	}
	length := C.GetArrayLength(env, C.jarray(jArr))
	ret := make([]string, int(length))
	for i := 0; i < int(length); i++ {
		ret[i] = GoString(env, C.jstring(C.GetObjectArrayElement(env, jArr, C.jsize(i))))
	}
	return ret
}

// JByteArray converts the provided Go byte slice into a Java byte array.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JByteArray(jEnv interface{}, bytes []byte) unsafe.Pointer {
	if bytes == nil {
		return nil
	}
	env := getEnv(jEnv)
	ret := C.NewByteArray(env, C.jsize(len(bytes)))
	if len(bytes) > 0 {
		C.SetByteArrayRegion(env, ret, 0, C.jsize(len(bytes)), (*C.jbyte)(unsafe.Pointer(&bytes[0])))
	}
	return unsafe.Pointer(ret)
}

// GoByteArray converts the provided Java byte array into a Go byte slice.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoByteArray(jEnv, jArr interface{}) (ret []byte) {
	env := getEnv(jEnv)
	arr := getByteArray(jArr)
	if arr == nil {
		return
	}
	length := int(C.GetArrayLength(env, C.jarray(arr)))
	ret = make([]byte, length)
	bytes := C.GetByteArrayElements(env, arr, nil)
	defer C.ReleaseByteArrayElements(env, arr, 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
}

// JByteArrayArray converts the provided [][]byte value into a Java array of
// byte arrays.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JByteArrayArray(jEnv interface{}, arr [][]byte) unsafe.Pointer {
	if arr == nil {
		return nil
	}
	env := getEnv(jEnv)
	ret := C.NewObjectArray(env, C.jsize(len(arr)), jByteArrayClass, nil)
	for i, elem := range arr {
		jElem := JByteArray(env, elem)
		C.SetObjectArrayElement(env, ret, C.jsize(i), C.jobject(jElem))
	}
	return unsafe.Pointer(ret)
}

// GoByteArrayArray converts the provided Java array of byte arrays into a Go
// [][]byte value.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoByteArrayArray(jEnv, jArr interface{}) (ret [][]byte) {
	env := getEnv(jEnv)
	arr := getObjectArray(jArr)
	if arr == nil {
		return
	}
	length := int(C.GetArrayLength(env, C.jarray(arr)))
	ret = make([][]byte, length)
	for i := 0; i < length; i++ {
		ret[i] = GoByteArray(env, C.GetObjectArrayElement(env, arr, C.jsize(i)))
	}
	return
}

// JVDLValueArray converts the provided Go slice of *vdl.Value values into a
// Java array of VdlValue objects.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JVDLValueArray(jEnv interface{}, arr []*vdl.Value) (unsafe.Pointer, error) {
	valarr := make([]interface{}, len(arr))
	for i, val := range arr {
		var err error
		if valarr[i], err = JVomCopy(jEnv, val, jVdlValueClass); err != nil {
			return nil, err
		}
	}
	return JObjectArray(jEnv, valarr, jVdlValueClass), nil
}

// GoVDLValueArray converts the provided Java array of VdlValue objects into a
// Go slice of *vdl.Value values.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoVDLValueArray(jEnv, jArr interface{}) ([]*vdl.Value, error) {
	valarr := GoObjectArray(jEnv, jArr)
	vals := make([]*vdl.Value, len(valarr))
	for i, jVal := range valarr {
		var err error
		// THIS GUY MESSES UP.
		if vals[i], err = GoVomCopyValue(jEnv, jVal); err != nil {
			return nil, err
		}
	}
	return vals, nil
}

// JObjectMap converts the provided Go map of Java objects into a Java
// object map.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JObjectMap(jEnv interface{}, goMap map[interface{}]interface{}) (unsafe.Pointer, error) {
	env := getEnv(jEnv)
	jMap, err := NewObject(env, jHashMapClass, nil)
	if err != nil {
		return nil, err
	}
	for jKey, jVal := range goMap {
		if _, err := CallObjectMethod(env, jMap, "put", []Sign{ObjectSign, ObjectSign}, ObjectSign, getObject(jKey), getObject(jVal)); err != nil {
			return nil, err
		}
	}
	return unsafe.Pointer(jMap), nil
}

// JObjectMultimap converts the provided Go map of Java objects into a Java
// object multimap.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JObjectMultimap(jEnv interface{}, goMap map[interface{}][]interface{}) (unsafe.Pointer, error) {
	env := getEnv(jEnv)
	jMap, err := NewObject(env, jHashMultimapClass, nil)
	if err != nil {
		return nil, err
	}
	for jKey, jVals := range goMap {
		for _, jVal := range jVals {
			if _, err := CallBooleanMethod(env, jMap, "put", []Sign{ObjectSign, ObjectSign}, getObject(jKey), getObject(jVal)); err != nil {
				return nil, err
			}
		}
	}
	return unsafe.Pointer(jMap), nil
}

// GoObjectMap converts the provided Java object map into a Go map of Java
// objects.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoObjectMap(jEnv, jObjMap interface{}) (map[unsafe.Pointer]unsafe.Pointer, error) {
	env := getEnv(jEnv)
	jMap := getObject(jObjMap)
	jKeySet, err := CallObjectMethod(env, jMap, "keySet", nil, SetSign)
	if err != nil {
		return nil, err
	}
	keysArr, err := CallObjectArrayMethod(env, jKeySet, "toArray", nil, ObjectSign)
	if err != nil {
		return nil, err
	}
	ret := make(map[unsafe.Pointer]unsafe.Pointer)
	for _, jKey := range keysArr {
		jVal, err := CallObjectMethod(env, jMap, "get", []Sign{ObjectSign}, ObjectSign, jKey)
		if err != nil {
			return nil, err
		}
		ret[jKey] = jVal
	}
	return ret, nil
}

// JFieldIDPtr returns the Java field ID for the given object (i.e., non-static)
// field, or an error if the field couldn't be found.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JFieldIDPtr(jEnv, jClass interface{}, name string, sign Sign) (unsafe.Pointer, error) {
	env := getEnv(jEnv)
	class := getClass(jClass)
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))
	cSign := C.CString(string(sign))
	defer C.free(unsafe.Pointer(cSign))
	ptr := unsafe.Pointer(C.GetFieldID(env, class, cName, cSign))
	if err := JExceptionMsg(env); err != nil || ptr == nil {
		return nil, fmt.Errorf("couldn't find field %s: %v", name, err)
	}
	return ptr, nil
}

// JStaticFieldIDPtr returns the Java field ID for the given static field,
// or an error if the field couldn't be found.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JStaticFieldIDPtr(jEnv, jClass interface{}, name string, sign Sign) (unsafe.Pointer, error) {
	env := getEnv(jEnv)
	class := getClass(jClass)
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))
	cSign := C.CString(string(sign))
	defer C.free(unsafe.Pointer(cSign))
	ptr := unsafe.Pointer(C.GetStaticFieldID(env, class, cName, cSign))
	if err := JExceptionMsg(env); err != nil || ptr == nil {
		return nil, fmt.Errorf("couldn't find field %s: %v", name, err)
	}
	return ptr, nil
}

// JMethodID returns the Java method ID for the given instance (non-static)
// method, or an error if the method couldn't be found.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JMethodID(jEnv, jClass interface{}, name string, signature Sign) (unsafe.Pointer, error) {
	env := getEnv(jEnv)
	class := getClass(jClass)
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))
	cSignature := C.CString(string(signature))
	defer C.free(unsafe.Pointer(cSignature))
	mid := C.GetMethodID(env, class, cName, cSignature)
	if err := JExceptionMsg(env); err != nil || mid == C.jmethodID(nil) {
		return nil, fmt.Errorf("couldn't find method %q with signature %v.", name, signature)
	}
	return unsafe.Pointer(mid), nil
}

// JStaticMethodID returns the Java method ID for the given static method, or an
// error if the method couldn't be found.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JStaticMethodID(jEnv, jClass interface{}, name string, signature Sign) (unsafe.Pointer, error) {
	env := getEnv(jEnv)
	class := getClass(jClass)
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))
	cSignature := C.CString(string(signature))
	defer C.free(unsafe.Pointer(cSignature))
	mid := C.GetStaticMethodID(env, class, cName, cSignature)
	if err := JExceptionMsg(env); err != nil || mid == C.jmethodID(nil) {
		return nil, fmt.Errorf("couldn't find method %s with a given signature.", name)
	}
	return unsafe.Pointer(mid), nil
}

// JFindClass returns the global reference to the Java class with the
// given pathname, or an error if the class cannot be found.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JFindClass(jEnv interface{}, name string) (unsafe.Pointer, error) {
	env := getEnv(jEnv)
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))
	class := C.FindClass(env, cName)
	if err := JExceptionMsg(env); err != nil || class == nil {
		return nil, fmt.Errorf("couldn't find class %s: %v", name, err)
	}
	return NewGlobalRef(env, C.jobject(class)), nil
}

// GoTime converts the provided Java DateTime object into a Go time.Time value.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoTime(jEnv, jTimeObj interface{}) (time.Time, error) {
	jTime := getObject(jTimeObj)
	if jTime == nil {
		return time.Time{}, nil
	}
	millis, err := CallLongMethod(jEnv, jTime, "getMillis", nil)
	if err != nil {
		return time.Time{}, err
	}
	sec := millis / 1000
	nsec := (millis % 1000) * 1000000
	return time.Unix(sec, nsec), nil
}

// JTime converts the provided Go time.Time value into a Java DateTime
// object.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JTime(jEnv interface{}, t time.Time) (unsafe.Pointer, error) {
	millis := t.UnixNano() / 1000000
	return NewObject(jEnv, jDateTimeClass, []Sign{LongSign}, millis)
}

// GoDuration converts the provided Java Duration object into a Go time.Duration
// value.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoDuration(jEnv interface{}, jDuration interface{}) (time.Duration, error) {
	millis, err := CallLongMethod(jEnv, jDuration, "getMillis", nil)
	if err != nil {
		return 0, err
	}
	return time.Duration(millis) * time.Millisecond, nil
}

// JDuration converts the provided Go time.Duration value into a Java
// Duration object.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JDuration(jEnv interface{}, d time.Duration) (unsafe.Pointer, error) {
	millis := d.Nanoseconds() / 1000000
	return NewObject(jEnv, jDurationClass, []Sign{LongSign}, int64(millis))
}

// Various functions that cast CGO types from various other packages into this
// package's types.
func getEnv(jEnv interface{}) *C.JNIEnv {
	return (*C.JNIEnv)(unsafe.Pointer(PtrValue(jEnv)))
}
func getJVM(jVM interface{}) *C.JavaVM {
	return (*C.JavaVM)(unsafe.Pointer(PtrValue(jVM)))
}
func getByteArray(jByteArray interface{}) C.jbyteArray {
	return C.jbyteArray(unsafe.Pointer(PtrValue(jByteArray)))
}
func getObject(jObj interface{}) C.jobject {
	return C.jobject(unsafe.Pointer(PtrValue(jObj)))
}
func getClass(jClass interface{}) C.jclass {
	return C.jclass(unsafe.Pointer(PtrValue(jClass)))
}
func getString(jString interface{}) C.jstring {
	return C.jstring(unsafe.Pointer(PtrValue(jString)))
}
func getObjectArray(jArray interface{}) C.jobjectArray {
	return C.jobjectArray(unsafe.Pointer(PtrValue(jArray)))
}
