// 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"
	"sync"
	"unsafe"
)

// #include "jni_wrapper.h"
import "C"

// NewGlobalRef creates a new global reference to the object referred to by the
// obj argument.  The obj argument may be a global or local reference. Global
// references must be explicitly disposed of by calling DeleteGlobalRef().
func NewGlobalRef(env Env, obj Object) Object {
	if obj.IsNull() {
		return obj
	}
	return Object(uintptr(unsafe.Pointer(C.NewGlobalRef(env.value(), obj.value()))))
}

// DeleteGlobalRef deletes the global reference pointed to by obj.
func DeleteGlobalRef(env Env, obj Object) {
	if !obj.IsNull() {
		C.DeleteGlobalRef(env.value(), obj.value())
	}
}

// NewLocalRef creates a new local reference that refers to the same object
// as obj. The given obj may be a global or local reference.
func NewLocalRef(env Env, obj Object) Object {
	if obj.IsNull() {
		return obj
	}
	return Object(uintptr(unsafe.Pointer(C.NewLocalRef(env.value(), obj.value()))))
}

// DeleteLocalRef deletes the local reference pointed to by obj.
func DeleteLocalRef(env Env, obj Object) {
	if !obj.IsNull() {
		C.DeleteLocalRef(env.value(), obj.value())
	}
}

// IsGlobalRef returns true iff the reference pointed to by obj is a global reference.
func IsGlobalRef(env Env, obj Object) bool {
	return !obj.IsNull() && C.GetObjectRefType(env.value(), obj.value()) == C.JNIGlobalRefType
}

// IsLocalRef returns true iff the reference pointed to by obj is a local reference.
func IsLocalRef(env Env, obj Object) bool {
	return obj.IsNull() || C.GetObjectRefType(env.value(), obj.value()) == C.JNILocalRefType
}

// GoRef creates a new reference to the value addressed by the provided pointer.
// The value will remain referenced until it is explicitly unreferenced using
// goUnref().
func GoRef(valptr interface{}) {
	if !IsPointer(valptr) {
		panic("must pass pointer value to goRef")
	}
	goRefs.ref(valptr)
}

// GoUnref removes a previously added reference to the value addressed by the
// provided pointer.  If the value hasn't been ref-ed (a bug?), this unref will
// be a no-op.
func GoUnref(valptr interface{}) {
	if !IsPointer(valptr) {
		panic("must pass pointer value to goUnref")
	}
	goRefs.unref(valptr)
}

// IsPointer returns true iff the provided value is a pointer.
func IsPointer(val interface{}) bool {
	v := reflect.ValueOf(val)
	return v.Kind() == reflect.Ptr || v.Kind() == reflect.UnsafePointer
}

// PtrValue returns the value of the pointer as a uintptr.
func PtrValue(ptr interface{}) uintptr {
	v := reflect.ValueOf(ptr)
	if v.Kind() != reflect.Ptr && v.Kind() != reflect.UnsafePointer {
		panic(fmt.Sprintf("must pass pointer value to PtrValue, was %v ", v.Type()))
	}
	return v.Pointer()
}

// DerefOrDie dereferences the provided (pointer) value, or panic-s if the value
// isn't of pointer type.
func DerefOrDie(i interface{}) interface{} {
	v := reflect.ValueOf(i)
	if v.Kind() != reflect.Ptr {
		panic(fmt.Sprintf("want reflect.Ptr value for %v, have %v", i, v.Type()))
	}
	return v.Elem().Interface()
}

// NativePtr returns the value of the provided Go pointer as an unsafe.Pointer.
// This function should only be used for converting Go pointers that have been
// passed in to Java and then back into Go, and are of (local-package) type
// C.jlong.
func NativePtr(goPtr interface{}) unsafe.Pointer {
	v := reflect.ValueOf(goPtr)
	return unsafe.Pointer(uintptr(v.Int()))
}

// goRefs stores references to instances of various Go types, namely instances
// that are referenced only by the Java code.  The only purpose of this store
// is to prevent Go runtime from garbage collecting those instances.
var goRefs = newSafeRefCounter()

type refData struct {
	instance interface{}
	count    int
}

// newSafeRefCounter returns a new instance of a thread-safe reference counter.
func newSafeRefCounter() *safeRefCounter {
	return &safeRefCounter{
		refs: make(map[uintptr]*refData),
	}
}

// safeRefCounter is a thread-safe reference counter.
type safeRefCounter struct {
	lock sync.Mutex
	refs map[uintptr]*refData
}

// ref increases the reference count to the given valptr by 1.
func (c *safeRefCounter) ref(valptr interface{}) {
	p := PtrValue(valptr)
	c.lock.Lock()
	defer c.lock.Unlock()
	ref, ok := c.refs[p]
	if !ok {
		c.refs[p] = &refData{
			instance: valptr,
			count:    1,
		}
	} else {
		ref.count++
	}
}

// unref decreases the reference count of the given valptr by 1, returning
// the new reference count value.
func (c *safeRefCounter) unref(valptr interface{}) int {
	c.lock.Lock()
	defer c.lock.Unlock()
	p := PtrValue(valptr)
	ref, ok := c.refs[p]
	if !ok {
		panic(fmt.Sprintf("Unrefing pointer %d of type %T that hasn't been refed before", int64(p), valptr))
	}
	count := ref.count
	if count == 0 {
		panic(fmt.Sprintf("Ref count for pointer %d of type %T is zero", int64(p), valptr))
	}
	if count > 1 {
		ref.count--
		return ref.count
	}
	delete(c.refs, p)
	return 0
}
