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

import (
	"fmt"
	"log"
	"runtime"
	"unsafe"

	"v.io/v23/context"
	jutil "v.io/x/jni/util"
)

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

type goContextKey string

type goContextValue struct {
	jObj C.jobject
}

// JavaContext converts the provided Go Context into a Java Context.
// 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 JavaContext(jEnv interface{}, ctx *context.T, cancel context.CancelFunc) (unsafe.Pointer, error) {
	cancelPtr := int64(0)
	if cancel != nil {
		cancelPtr = int64(jutil.PtrValue(&cancel))
	}
	jCtx, err := jutil.NewObject(jEnv, jVContextImplClass, []jutil.Sign{jutil.LongSign, jutil.LongSign}, int64(jutil.PtrValue(ctx)), cancelPtr)
	if err != nil {
		return nil, err
	}
	jutil.GoRef(ctx) // Un-refed when the Java context object is finalized.
	if cancel != nil {
		jutil.GoRef(&cancel) // Un-refed when the Java context object is finalized.
	}
	return jCtx, err
}

// GoContext converts the provided Java Context into a Go context.
// 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 GoContext(jEnv, jContext interface{}) (*context.T, error) {
	if jutil.IsNull(jContext) {
		return nil, nil
	}
	goCtxPtr, err := jutil.CallLongMethod(jEnv, jContext, "nativePtr", nil)
	if err != nil {
		return nil, err
	}
	return (*context.T)(jutil.Ptr(goCtxPtr)), nil
}

// JavaCountDownLatch creates a Java CountDownLatch object with an initial count
// of one that counts down (to zero) the moment the value is sent on the
// provided Go channel or if the channel gets closed.
// 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 JavaCountDownLatch(jEnv interface{}, c <-chan struct{}) (unsafe.Pointer, error) {
	if c == nil {
		return nil, nil
	}
	jLatchObj, err := jutil.NewObject(jEnv, jCountDownLatchClass, []jutil.Sign{jutil.IntSign}, int(1))
	if err != nil {
		return nil, err
	}
	// Reference Java CountDownLatch; it will be de-referenced when the goroutine below exits.
	jLatch := C.jobject(jutil.NewGlobalRef(jEnv, jLatchObj))
	go func() {
		<-c
		javaEnv, freeFunc := jutil.GetEnv()
		jenv := (*C.JNIEnv)(javaEnv)
		defer freeFunc()
		if err := jutil.CallVoidMethod(jenv, jLatch, "countDown", nil); err != nil {
			log.Printf("Error decrementing CountDownLatch: %v", err)
		}
		jutil.DeleteGlobalRef(jenv, jLatch)
	}()
	return unsafe.Pointer(jLatch), nil
}

// GoContextKey creates a Go Context key given the Java Context key.  The
// returned key guarantees that the two Java keys will be equal iff (1) they
// belong to the same class, and (2) they have the same hashCode().
// 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 GoContextKey(jEnv, jKey interface{}) (interface{}, error) {
	// Create a lookup key we use to map Java context keys to Go context keys.
	hashCode, err := jutil.CallIntMethod(jEnv, jKey, "hashCode", nil)
	if err != nil {
		return nil, err
	}
	jClass, err := jutil.CallObjectMethod(jEnv, jKey, "getClass", nil, classSign)
	if err != nil {
		return nil, err
	}
	className, err := jutil.CallStringMethod(jEnv, jClass, "getName", nil)
	if err != nil {
		return nil, err
	}
	return goContextKey(fmt.Sprintf("%s:%d", className, hashCode)), nil
}

// GoContextValue returns the Go Context value given the Java Context 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 GoContextValue(jEnv, jValueObj interface{}) (interface{}, error) {
	// Reference Java object; it will be de-referenced when the Go wrapper
	// object created below is garbage-collected (via the finalizer we setup
	// just below.)
	jValue := C.jobject(jutil.NewGlobalRef(jEnv, jValueObj))
	value := &goContextValue{
		jObj: jValue,
	}
	runtime.SetFinalizer(value, func(value *goContextValue) {
		javaEnv, freeFunc := jutil.GetEnv()
		jenv := (*C.JNIEnv)(javaEnv)
		defer freeFunc()
		jutil.DeleteGlobalRef(jenv, value.jObj)
	})
	return value, nil
}

// JavaContextValue returns the Java Context value given the Go Context 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 JavaContextValue(jEnv interface{}, value interface{}) (unsafe.Pointer, error) {
	if value == nil {
		return nil, nil
	}
	val, ok := value.(*goContextValue)
	if !ok {
		return nil, fmt.Errorf("Invalid type %T for value %v, wanted goContextValue", value, value)
	}
	return unsafe.Pointer(val.jObj), nil
}
