// 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 (
	"errors"
	"unsafe"

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

// #include "jni.h"
// #include <stdlib.h>
import "C"

var (
	classSign      = jutil.ClassSign("java.lang.Class")
	doneReasonSign = jutil.ClassSign("io.v.v23.context.VContext$DoneReason")
	// Global reference for io.v.v23.context.VContext class.
	jVContextClass jutil.Class
	// Global reference for io.v.v23.context.VContext$DoneReason
	jDoneReasonClass jutil.Class
)

// Init initializes the JNI code with the given Java environment. This method
// must be called from the main Java thread.
func Init(env jutil.Env) error {
	// Cache global references to all Java classes used by the package.  This is
	// necessary because JNI gets access to the class loader only in the system
	// thread, so we aren't able to invoke FindClass in other threads.
	var err error
	jVContextClass, err = jutil.JFindClass(env, "io/v/v23/context/VContext")
	if err != nil {
		return err
	}
	jDoneReasonClass, err = jutil.JFindClass(env, "io/v/v23/context/VContext$DoneReason")
	if err != nil {
		return err
	}
	return nil
}

//export Java_io_v_v23_context_VContext_nativeCreate
func Java_io_v_v23_context_VContext_nativeCreate(jenv *C.JNIEnv, jVContext C.jclass) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	ctx, _ := context.RootContext()
	jContext, err := JavaContext(env, ctx, nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jContext))
}

//export Java_io_v_v23_context_VContext_nativeCancel
func Java_io_v_v23_context_VContext_nativeCancel(jenv *C.JNIEnv, jVContext C.jobject, goCancelRef C.jlong) {
	(*(*context.CancelFunc)(jutil.GoRefValue(jutil.Ref(goCancelRef))))()
}

//export Java_io_v_v23_context_VContext_nativeIsCanceled
func Java_io_v_v23_context_VContext_nativeIsCanceled(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong) C.jboolean {
	if (*(*context.T)(jutil.GoRefValue(jutil.Ref(goRef)))).Err() == nil {
		return C.JNI_FALSE
	}
	return C.JNI_TRUE
}

//export Java_io_v_v23_context_VContext_nativeDeadline
func Java_io_v_v23_context_VContext_nativeDeadline(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	d, ok := (*(*context.T)(jutil.GoRefValue(jutil.Ref(goRef)))).Deadline()
	if !ok {
		return nil
	}
	jDeadline, err := jutil.JTime(env, d)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jDeadline))
}

//export Java_io_v_v23_context_VContext_nativeOnDone
func Java_io_v_v23_context_VContext_nativeOnDone(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	ctx := (*(*context.T)(jutil.GoRefValue(jutil.Ref(goRef))))
	c := ctx.Done()
	if c == nil {
		jutil.CallbackOnFailure(env, jCallback, errors.New("Context isn't cancelable"))
		return
	}
	jutil.DoAsyncCall(env, jCallback, func() (jutil.Object, error) {
		<-c
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jReason, err := JavaContextDoneReason(env, ctx.Err())
		if err != nil {
			return jutil.NullObject, err
		}
		// Must grab a global reference as we free up the env and all local references that come along
		// with it.
		return jutil.NewGlobalRef(env, jReason), nil // Un-refed in DoAsyncCall
	})
}

//export Java_io_v_v23_context_VContext_nativeValue
func Java_io_v_v23_context_VContext_nativeValue(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong, jKeySign C.jstring) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	key := goContextKey(jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jKeySign)))))
	value := (*(*context.T)(jutil.GoRefValue(jutil.Ref(goRef)))).Value(key)
	jValue, err := JavaContextValue(env, value)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jValue))
}

//export Java_io_v_v23_context_VContext_nativeWithCancel
func Java_io_v_v23_context_VContext_nativeWithCancel(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	ctx, cancelFunc := context.WithCancel((*context.T)(jutil.GoRefValue(jutil.Ref(goRef))))
	jCtx, err := JavaContext(env, ctx, cancelFunc)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jCtx))
}

//export Java_io_v_v23_context_VContext_nativeWithDeadline
func Java_io_v_v23_context_VContext_nativeWithDeadline(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong, jDeadline C.jobject) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	deadline, err := jutil.GoTime(env, jutil.Object(uintptr(unsafe.Pointer(jDeadline))))
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	ctx, cancelFunc := context.WithDeadline((*context.T)(jutil.GoRefValue(jutil.Ref(goRef))), deadline)
	jCtx, err := JavaContext(env, ctx, cancelFunc)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jCtx))
}

//export Java_io_v_v23_context_VContext_nativeWithTimeout
func Java_io_v_v23_context_VContext_nativeWithTimeout(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong, jTimeout C.jobject) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	timeout, err := jutil.GoDuration(env, jutil.Object(uintptr(unsafe.Pointer(jTimeout))))
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	ctx, cancelFunc := context.WithTimeout((*context.T)(jutil.GoRefValue(jutil.Ref(goRef))), timeout)
	jCtx, err := JavaContext(env, ctx, cancelFunc)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jCtx))
}

//export Java_io_v_v23_context_VContext_nativeWithValue
func Java_io_v_v23_context_VContext_nativeWithValue(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong, goCancelRef C.jlong, jKeySign C.jstring, jValue C.jobject) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	key := goContextKey(jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jKeySign)))))
	value, err := GoContextValue(env, jutil.Object(uintptr(unsafe.Pointer(jValue))))
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	ctx := context.WithValue((*context.T)(jutil.GoRefValue(jutil.Ref(goRef))), key, value)
	var cancel context.CancelFunc
	if goCancelRef != 0 {
		cancel = (*(*context.CancelFunc)(jutil.GoRefValue(jutil.Ref(goCancelRef))))
	}
	jCtx, err := JavaContext(env, ctx, cancel)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jCtx))
}

//export Java_io_v_v23_context_VContext_nativeFinalize
func Java_io_v_v23_context_VContext_nativeFinalize(jenv *C.JNIEnv, jVContext C.jobject, goRef C.jlong, goCancelRef C.jlong) {
	jutil.GoDecRef(jutil.Ref(goRef))
	if jutil.Ref(goCancelRef) != jutil.NullRef {
		jutil.GoDecRef(jutil.Ref(goCancelRef))
	}

}
