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

import (
	"fmt"
	"reflect"
	"time"
	"unsafe"
)

// #include <stdlib.h>
// #include "jni_wrapper.h"
//
// static jvalue* allocJValueArray(int elements) {
//   return malloc(sizeof(jvalue) * elements);
// }
//
// static setJValueArrayElement(jvalue* arr, int index, jvalue val) {
//   arr[index] = val;
// }
//
import "C"

// jArg converts a Go argument to a Java argument.  It uses the provided sign to
// validate that the argument is of a compatible type.
func jArg(env *C.JNIEnv, v interface{}, sign Sign) (unsafe.Pointer, bool) {
	rv := reflect.ValueOf(v)
	if !rv.IsValid() { // nil value
		jv := C.jobject(nil)
		return unsafe.Pointer(&jv), true
	}
	if rv.Type() == reflect.TypeOf(time.Time{}) {
		if sign != DateTimeSign {
			return unsafe.Pointer(nil), false
		}
		jv, err := JTime(env, rv.Interface().(time.Time))
		if err != nil {
			return unsafe.Pointer(nil), false
		}
		return unsafe.Pointer(&jv), true
	}
	if rv.Type() == reflect.TypeOf(time.Duration(0)) {
		if sign != DurationSign {
			return unsafe.Pointer(nil), false
		}
		jv, err := JDuration(env, rv.Interface().(time.Duration))
		if err != nil {
			return unsafe.Pointer(nil), false
		}
		return unsafe.Pointer(&jv), true
	}
	if rv.Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
		if sign != VExceptionSign {
			return unsafe.Pointer(nil), false
		}
		jv, err := JVException(env, rv.Interface().(error))
		if err != nil {
			return unsafe.Pointer(nil), false
		}
		return unsafe.Pointer(&jv), true
	}
	if rv.Kind() == reflect.Ptr || rv.Kind() == reflect.UnsafePointer {
		rv = reflect.ValueOf(rv.Pointer()) // Convert the pointer's address to a uintptr
	}
	switch rv.Kind() {
	case reflect.Bool:
		if sign != BoolSign {
			return unsafe.Pointer(nil), false
		}
		jv := C.jboolean(C.JNI_FALSE)
		if rv.Bool() {
			jv = C.JNI_TRUE
		}
		return unsafe.Pointer(&jv), true
	case reflect.Int, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uint8:
		if !isSignOneOf(sign, []Sign{ByteSign, ShortSign, IntSign, LongSign}) {
			return unsafe.Pointer(nil), false
		}
		jv := C.jint(rv.Int())
		return unsafe.Pointer(&jv), true
	case reflect.Int64:
		if sign != LongSign {
			return unsafe.Pointer(nil), false
		}
		jv := C.jlong(rv.Int())
		return unsafe.Pointer(&jv), true
	case reflect.Uint64:
		if sign != LongSign {
			return unsafe.Pointer(nil), false
		}
		jv := C.jlong(rv.Uint())
		return unsafe.Pointer(&jv), true
	case reflect.Uintptr:
		if isSignOneOf(sign, []Sign{ByteSign, BoolSign, CharSign, ShortSign, IntSign, FloatSign, DoubleSign}) {
			return unsafe.Pointer(nil), false
		}
		jv := C.jlong(rv.Uint())
		return unsafe.Pointer(&jv), true
	case reflect.String:
		if sign != StringSign {
			return unsafe.Pointer(nil), false
		}
		// JString allocates the strings locally, so they are freed automatically when we return to Java.
		jv := JString(env, rv.String())
		if jv == nil {
			return unsafe.Pointer(nil), false
		}
		return unsafe.Pointer(&jv), true
	case reflect.Slice, reflect.Array:
		switch rv.Type().Elem().Kind() {
		case reflect.Uint8:
			if sign != ArraySign(ByteSign) {
				return unsafe.Pointer(nil), false
			}
			bs := rv.Interface().([]byte)
			jv := JByteArray(env, bs)
			return unsafe.Pointer(&jv), true
		case reflect.String:
			if sign != ArraySign(StringSign) {
				return unsafe.Pointer(nil), false
			}
			// TODO(bprosnitz) We should handle objects by calling jArg recursively. We need a way to get the sign of the target type or treat it as an Object for non-string types.
			strs := rv.Interface().([]string)
			jv := JStringArray(env, strs)
			return unsafe.Pointer(&jv), true
		default:
			return unsafe.Pointer(nil), false
		}
	default:
		return unsafe.Pointer(nil), false
	}
}

// jArgArray converts a slice of Go args to an array of Java args.  It uses the provided slice of
// Signs to validate that the arguments are of compatible types.
func jArgArray(env *C.JNIEnv, args []interface{}, argSigns []Sign) (jArr *C.jvalue, free func(), err error) {
	if len(argSigns) != len(args) {
		return (*C.jvalue)(nil), nil, fmt.Errorf("mismatch in number of arguments, want %d, got %d", len(argSigns), len(args))
	}
	jvalueArr := C.allocJValueArray(C.int(len(args)))
	for i, arg := range args {
		sign := argSigns[i]
		jValPtr, ok := jArg(env, arg, sign)
		if !ok {
			return (*C.jvalue)(nil), nil, fmt.Errorf("couldn't get Java value for argument #%d [%v] of expected type %v", i, arg, sign)
		}
		C.setJValueArrayElement(jvalueArr, C.int(i), *(*C.jvalue)(jValPtr))
	}
	freeFunc := func() {
		C.free(unsafe.Pointer(jvalueArr))
	}
	return jvalueArr, freeFunc, nil
}

// NewObject calls a java constructor through JNI, passing the specified args.
func NewObject(env interface{}, class interface{}, argSigns []Sign, args ...interface{}) (unsafe.Pointer, error) {
	if class == nil {
		panic("cannot call constructor of nil class")
	}
	jenv := getEnv(env)
	jclass := getClass(class)

	jcid, err := JMethodID(jenv, jclass, "<init>", FuncSign(argSigns, VoidSign))
	if err != nil {
		return nil, err
	}

	valArray, freeFunc, err := jArgArray(jenv, args, argSigns)
	if err != nil {
		return nil, err
	}
	defer freeFunc()

	ret := C.NewObjectA(jenv, jclass, C.jmethodID(jcid), valArray)
	err = JExceptionMsg(env)
	return unsafe.Pointer(ret), err
}

// setupMethodCall performs the shared preparation operations between various
// Java method invocation functions.
func setupMethodCall(env interface{}, object interface{}, name string, argSigns []Sign, retSign Sign, args []interface{}) (jenv *C.JNIEnv, jobject C.jobject, jmid C.jmethodID, jvalArray *C.jvalue, freeFunc func(), err error) {
	jenv = getEnv(env)
	jobject = getObject(object)
	jclass := C.GetObjectClass(jenv, jobject)

	var id unsafe.Pointer
	id, err = JMethodID(jenv, jclass, name, FuncSign(argSigns, retSign))
	if err != nil {
		return
	}
	jmid = C.jmethodID(id)
	jvalArray, freeFunc, err = jArgArray(jenv, args, argSigns)
	return
}

// setupStaticMethodCall performs the shared preparation operations between
// various Java static method invocation functions.
func setupStaticMethodCall(env interface{}, class interface{}, name string, argSigns []Sign, retSign Sign, args []interface{}) (jenv *C.JNIEnv, jclass C.jclass, jmid C.jmethodID, jvalArray *C.jvalue, freeFunc func(), err error) {
	jenv = getEnv(env)
	jclass = getClass(class)

	var id unsafe.Pointer
	id, err = JStaticMethodID(jenv, jclass, name, FuncSign(argSigns, retSign))
	if err != nil {
		return
	}
	jmid = C.jmethodID(id)
	jvalArray, freeFunc, err = jArgArray(jenv, args, argSigns)
	return
}

// CallObjectMethod calls a Java method that returns a java object.
func CallObjectMethod(env interface{}, object interface{}, name string, argSigns []Sign, retSign Sign, args ...interface{}) (unsafe.Pointer, error) {
	switch retSign {
	case ByteSign, CharSign, ShortSign, LongSign, FloatSign, DoubleSign, BoolSign, IntSign, VoidSign:
		panic(fmt.Sprintf("Illegal call to CallObjectMethod on method with return sign %s", retSign))
	}
	jenv, jobject, jmid, valArray, freeFunc, err := setupMethodCall(env, object, name, argSigns, retSign, args)
	if err != nil {
		return nil, err
	}
	defer freeFunc()
	ret := C.CallObjectMethodA(jenv, jobject, jmid, valArray)
	return unsafe.Pointer(ret), JExceptionMsg(env)
}

// CallStringMethod calls a Java method that returns a string.
func CallStringMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) (string, error) {
	jstr, err := CallObjectMethod(env, object, name, argSigns, StringSign, args...)
	return GoString(env, jstr), err
}

// CallByteArrayMethod calls a Java method that returns a byte array.
func CallByteArrayMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) ([]byte, error) {
	jArr, err := CallObjectMethod(env, object, name, argSigns, ArraySign(ByteSign), args...)
	if err != nil {
		return nil, err
	}
	return GoByteArray(env, jArr), nil
}

// CallObjectArrayMethod calls a Java method that returns an object array.
func CallObjectArrayMethod(env interface{}, object interface{}, name string, argSigns []Sign, retElemSign Sign, args ...interface{}) ([]unsafe.Pointer, error) {
	jenv := getEnv(env)
	jArr, err := CallObjectMethod(env, object, name, argSigns, ArraySign(retElemSign), args...)
	if err != nil {
		return nil, err
	}
	if jArr == nil {
		return nil, nil
	}
	ret := make([]unsafe.Pointer, int(C.GetArrayLength(jenv, C.jarray(jArr))))
	for i, _ := range ret {
		ret[i] = unsafe.Pointer(C.GetObjectArrayElement(jenv, C.jobjectArray(jArr), C.jsize(i)))
	}
	return ret, nil
}

// CallStringArrayMethod calls a Java method that returns an string array.
func CallStringArrayMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) ([]string, error) {
	objarr, err := CallObjectArrayMethod(env, object, name, argSigns, StringSign, args...)
	if err != nil {
		return nil, err
	}
	strs := make([]string, len(objarr))
	for i, obj := range objarr {
		strs[i] = GoString(env, obj)
	}
	return strs, nil
}

// CallMapMethod calls a Java method that returns a Map.
func CallMapMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) (map[unsafe.Pointer]unsafe.Pointer, error) {
	jMap, err := CallObjectMethod(env, object, name, argSigns, MapSign, args...)
	if err != nil {
		return nil, err
	}
	if jMap == nil {
		return nil, nil
	}
	jEntrySet, err := CallObjectMethod(env, jMap, "entrySet", nil, SetSign)
	if err != nil {
		return nil, err
	}
	jIter, err := CallObjectMethod(env, jEntrySet, "iterator", nil, IteratorSign)
	if err != nil {
		return nil, err
	}
	ret := make(map[unsafe.Pointer]unsafe.Pointer)
	for {
		if hasNext, err := CallBooleanMethod(env, jIter, "hasNext", nil); err != nil {
			return nil, err
		} else if !hasNext {
			break
		}
		jEntry, err := CallObjectMethod(env, jIter, "next", nil, ObjectSign)
		if err != nil {
			return nil, err
		}
		jKey, err := CallObjectMethod(env, jEntry, "getKey", nil, ObjectSign)
		if err != nil {
			return nil, err
		}
		jValue, err := CallObjectMethod(env, jEntry, "getValue", nil, ObjectSign)
		if err != nil {
			return nil, err
		}
		ret[jKey] = jValue
	}
	return ret, nil
}

// CallMultimapMethod calls a Java method that returns a Multimap.
func CallMultimapMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) (map[unsafe.Pointer][]unsafe.Pointer, error) {
	jMultimap, err := CallObjectMethod(env, object, name, argSigns, MultimapSign, args...)
	if err != nil {
		return nil, err
	}
	if jMultimap == nil {
		return nil, nil
	}
	jEntrySet, err := CallObjectMethod(env, jMultimap, "entrySet", nil, SetSign)
	if err != nil {
		return nil, err
	}
	jIter, err := CallObjectMethod(env, jEntrySet, "iterator", nil, IteratorSign)
	if err != nil {
		return nil, err
	}
	ret := make(map[unsafe.Pointer][]unsafe.Pointer)
	for {
		if hasNext, err := CallBooleanMethod(env, jIter, "hasNext", nil); err != nil {
			return nil, err
		} else if !hasNext {
			break
		}
		jEntry, err := CallObjectMethod(env, jIter, "next", nil, ObjectSign)
		if err != nil {
			return nil, err
		}
		jKey, err := CallObjectMethod(env, jEntry, "getKey", nil, ObjectSign)
		if err != nil {
			return nil, err
		}
		jValue, err := CallObjectMethod(env, jEntry, "getValue", nil, ObjectSign)
		if err != nil {
			return nil, err
		}
		ret[jKey] = append(ret[jKey], jValue)
	}
	return ret, nil
}

// CallBooleanMethod calls a Java method that returns a boolean.
func CallBooleanMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) (bool, error) {
	jenv, jobject, jmid, valArray, freeFunc, err := setupMethodCall(env, object, name, argSigns, BoolSign, args)
	if err != nil {
		return false, err
	}
	defer freeFunc()
	ret := C.CallBooleanMethodA(jenv, jobject, jmid, valArray) != C.JNI_OK
	return ret, JExceptionMsg(env)
}

// CallIntMethod calls a Java method that returns an int.
func CallIntMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) (int, error) {
	jenv, jobject, jmid, valArray, freeFunc, err := setupMethodCall(env, object, name, argSigns, IntSign, args)
	if err != nil {
		return 0, err
	}
	defer freeFunc()
	ret := int(C.CallIntMethodA(jenv, jobject, jmid, valArray))
	return ret, JExceptionMsg(env)
}

// CallLongMethod calls a Java method that returns an int64.
func CallLongMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) (int64, error) {
	jenv, jobject, jmid, valArray, freeFunc, err := setupMethodCall(env, object, name, argSigns, LongSign, args)
	if err != nil {
		return 0, err
	}
	defer freeFunc()
	ret := int64(C.CallLongMethodA(jenv, jobject, jmid, valArray))
	return ret, JExceptionMsg(env)
}

// CallVoidMethod calls a Java method that doesn't return anything.
func CallVoidMethod(env interface{}, object interface{}, name string, argSigns []Sign, args ...interface{}) error {
	jenv, jobject, jmid, valArray, freeFunc, err := setupMethodCall(env, object, name, argSigns, VoidSign, args)
	if err != nil {
		return err
	}
	defer freeFunc()
	C.CallVoidMethodA(jenv, jobject, jmid, valArray)
	return JExceptionMsg(env)
}

// CallStaticObjectMethod calls a static Java method that returns a Java object.
func CallStaticObjectMethod(env interface{}, class interface{}, name string, argSigns []Sign, retSign Sign, args ...interface{}) (unsafe.Pointer, error) {
	switch retSign {
	case ByteSign, CharSign, ShortSign, LongSign, FloatSign, DoubleSign, BoolSign, IntSign, VoidSign:
		panic(fmt.Sprintf("Illegal call to CallStaticObjectMethod on method with return sign %s", retSign))
	}
	jenv, jclass, jmid, jvalArray, freeFunc, err := setupStaticMethodCall(env, class, name, argSigns, retSign, args)
	if err != nil {
		return nil, err
	}
	defer freeFunc()
	ret := C.CallStaticObjectMethodA(jenv, jclass, jmid, jvalArray)
	return unsafe.Pointer(ret), JExceptionMsg(env)
}

// CallStaticStringMethod calls a static Java method that returns a string.
func CallStaticStringMethod(env interface{}, class interface{}, name string, argSigns []Sign, args ...interface{}) (string, error) {
	jString, err := CallStaticObjectMethod(env, class, name, argSigns, StringSign, args...)
	return GoString(env, jString), err
}

// CallStaticByteArrayMethod calls a static Java method that returns a byte array.
func CallStaticByteArrayMethod(env interface{}, class interface{}, name string, argSigns []Sign, args ...interface{}) ([]byte, error) {
	jArr, err := CallStaticObjectMethod(env, class, name, argSigns, ArraySign(ByteSign), args...)
	if err != nil {
		return nil, err
	}
	return GoByteArray(env, jArr), nil
}

// CallStaticIntMethod calls a static Java method that returns an int.
func CallStaticIntMethod(env interface{}, class interface{}, name string, argSigns []Sign, args ...interface{}) (int, error) {
	jenv, jclass, jmid, jvalArray, freeFunc, err := setupStaticMethodCall(env, class, name, argSigns, IntSign, args)
	if err != nil {
		return 0, err
	}
	defer freeFunc()
	ret := int(C.CallStaticIntMethodA(jenv, jclass, jmid, jvalArray))
	return ret, JExceptionMsg(env)
}

// CallStaticVoidMethod calls a static Java method doesn't return anything.
func CallStaticVoidMethod(env interface{}, class interface{}, name string, argSigns []Sign, args ...interface{}) error {
	jenv, jclass, jmid, jvalArray, freeFunc, err := setupStaticMethodCall(env, class, name, argSigns, VoidSign, args)
	if err != nil {
		return err
	}
	defer freeFunc()
	C.CallStaticVoidMethodA(jenv, jclass, jmid, jvalArray)
	return JExceptionMsg(env)
}

func handleError(name string, err error) {
	if err != nil {
		panic(fmt.Sprintf("error while calling jni method %q: %v", name, err))
	}
}

func isSignOneOf(sign Sign, set []Sign) bool {
	for _, s := range set {
		if sign == s {
			return true
		}
	}
	return false
}
