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

import (
	"fmt"
	"time"
	"unsafe"

	"v.io/v23/context"
	"v.io/v23/namespace"
	"v.io/v23/naming"
	"v.io/v23/security/access"
	"v.io/v23/verror"
	jchannel "v.io/x/jni/impl/google/channel"
	jutil "v.io/x/jni/util"
	jcontext "v.io/x/jni/v23/context"
)

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

var (
	// Global reference for io.v.impl.google.namespace.NamespaceImpl class.
	jNamespaceImplClass jutil.Class
	// Global reference for io.v.v23.naming.GlobReply class.
	jGlobReplyClass jutil.Class
	// Global reference for io.v.v23.naming.MountEntry class.
	jMountEntryClass jutil.Class
	// Global reference for io.v.v23.security.access.Permissions
	jPermissionsClass 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 {
	var err error
	jNamespaceImplClass, err = jutil.JFindClass(env, "io/v/impl/google/namespace/NamespaceImpl")
	if err != nil {
		return err
	}
	jGlobReplyClass, err = jutil.JFindClass(env, "io/v/v23/naming/GlobReply")
	if err != nil {
		return err
	}
	jMountEntryClass, err = jutil.JFindClass(env, "io/v/v23/naming/MountEntry")
	if err != nil {
		return err
	}
	jPermissionsClass, err = jutil.JFindClass(env, "io/v/v23/security/access/Permissions")
	if err != nil {
		return err
	}
	return nil
}

func globArgs(env jutil.Env, jContext C.jobject, jPattern C.jstring, jOptions C.jobject) (context *context.T, pattern string, opts []naming.NamespaceOpt, err error) {
	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		return
	}
	opts, err = namespaceOptions(env, jutil.Object(uintptr(unsafe.Pointer(jOptions))))
	if err != nil {
		return
	}
	pattern = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jPattern))))
	return
}

func doGlob(env jutil.Env, n namespace.T, context *context.T, pattern string, opts []naming.NamespaceOpt) (jutil.Object, error) {
	c, err := n.Glob(context, pattern, opts...)
	if err != nil {
		return jutil.NullObject, err
	}
	valChan := make(chan interface{}, 100)
	go func() {
		for val := range c {
			valChan <- val
		}
		close(valChan)
	}()
	return jchannel.JavaIterable(env, valChan, func(env jutil.Env, val interface{}) (jutil.Object, error) {
		globReply, ok := val.(naming.GlobReply)
		if !ok {
			return jutil.NullObject, fmt.Errorf("Expected value of GlobReply type, got type %T: %v", val, val)
		}
		// Check for a canceled context error, we surface these as EOF.
		if errorEntry, ok := globReply.(*naming.GlobReplyError); ok {
			if verr, ok := errorEntry.Value.Error.(verror.E); ok && verr.ID == verror.ErrCanceled.ID {
				return jutil.NullObject, verr
			}
		}
		return jutil.JVomCopy(env, val, jGlobReplyClass)
	})
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeGlob
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeGlob(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jPattern C.jstring, jOptions C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	context, pattern, opts, err := globArgs(env, jContext, jPattern, jOptions)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	jutil.DoAsyncCall(env, jCallback, func(env jutil.Env) (jutil.Object, error) {
		return doGlob(env, n, context, pattern, opts)
	})
}

func mountArgs(env jutil.Env, jContext C.jobject, jName, jServer C.jstring, jDuration, jOptions C.jobject) (context *context.T, name, server string, duration time.Duration, options []naming.NamespaceOpt, err error) {
	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		return
	}
	name = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
	server = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jServer))))
	duration, err = jutil.GoDuration(env, jutil.Object(uintptr(unsafe.Pointer(jDuration))))
	if err != nil {
		return
	}
	options, err = namespaceOptions(env, jutil.Object(uintptr(unsafe.Pointer(jOptions))))
	return
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeMount
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeMount(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring, jServer C.jstring, jDuration C.jobject, jOptions C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	context, name, server, duration, options, err := mountArgs(env, jContext, jName, jServer, jDuration, jOptions)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	jutil.DoAsyncCall(env, jCallback, func(env jutil.Env) (jutil.Object, error) {
		return jutil.NullObject, n.Mount(context, name, server, duration, options...)
	})
}

func unmountArgs(env jutil.Env, jName, jServer C.jstring, jContext, jOptions C.jobject) (name, server string, context *context.T, options []naming.NamespaceOpt, err error) {
	name = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
	server = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jServer))))
	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		return
	}
	options, err = namespaceOptions(env, jutil.Object(uintptr(unsafe.Pointer(jOptions))))
	return
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeUnmount
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeUnmount(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring, jServer C.jstring, jOptions C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	name, server, context, options, err := unmountArgs(env, jName, jServer, jContext, jOptions)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	jutil.DoAsyncCall(env, jCallback, func(env jutil.Env) (jutil.Object, error) {
		return jutil.NullObject, n.Unmount(context, name, server, options...)
	})
}

func deleteArgs(env jutil.Env, jContext, jOptions C.jobject, jName C.jstring, jDeleteSubtree C.jboolean) (context *context.T, options []naming.NamespaceOpt, name string, deleteSubtree bool, err error) {
	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		return
	}
	options, err = namespaceOptions(env, jutil.Object(uintptr(unsafe.Pointer(jOptions))))
	if err != nil {
		return
	}
	name = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
	deleteSubtree = jDeleteSubtree == C.JNI_TRUE
	return
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeDelete
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeDelete(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring, jDeleteSubtree C.jboolean, jOptions C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	context, options, name, deleteSubtree, err := deleteArgs(env, jContext, jOptions, jName, jDeleteSubtree)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	jutil.DoAsyncCall(env, jCallback, func(env jutil.Env) (jutil.Object, error) {
		return jutil.NullObject, n.Delete(context, name, deleteSubtree, options...)
	})
}

func resolveArgs(env jutil.Env, jName C.jstring, jContext, jOptions C.jobject) (context *context.T, name string, options []naming.NamespaceOpt, err error) {
	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		return
	}
	options, err = namespaceOptions(env, jutil.Object(uintptr(unsafe.Pointer(jOptions))))
	if err != nil {
		return
	}
	name = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
	return
}

func doResolve(env jutil.Env, n namespace.T, context *context.T, name string, options []naming.NamespaceOpt) (jutil.Object, error) {
	entry, err := n.Resolve(context, name, options...)
	if err != nil {
		return jutil.NullObject, err
	}
	return jutil.JVomCopy(env, entry, jMountEntryClass)
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeResolve
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeResolve(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring, jOptions C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	context, name, options, err := resolveArgs(env, jName, jContext, jOptions)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	jutil.DoAsyncCall(env, jCallback, func(env jutil.Env) (jutil.Object, error) {
		return doResolve(env, n, context, name, options)
	})
}

func resolveToMountTableArgs(env jutil.Env, jContext, jOptions C.jobject, jName C.jstring) (context *context.T, options []naming.NamespaceOpt, name string, err error) {
	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		return
	}
	options, err = namespaceOptions(env, jutil.Object(uintptr(unsafe.Pointer(jOptions))))
	if err != nil {
		return
	}
	name = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
	return
}

func doResolveToMountTable(env jutil.Env, n namespace.T, context *context.T, name string, options []naming.NamespaceOpt) (jutil.Object, error) {
	entry, err := n.ResolveToMountTable(context, name, options...)
	if err != nil {
		return jutil.NullObject, err
	}
	return jutil.JVomCopy(env, entry, jMountEntryClass)
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeResolveToMountTable
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeResolveToMountTable(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring, jOptions C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	context, options, name, err := resolveToMountTableArgs(env, jContext, jOptions, jName)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	jutil.DoAsyncCall(env, jCallback, func(env jutil.Env) (jutil.Object, error) {
		return doResolveToMountTable(env, n, context, name, options)
	})
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeFlushCacheEntry
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeFlushCacheEntry(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring) C.jboolean {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	context, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		jutil.JThrowV(env, err)
		return C.JNI_FALSE
	}
	result := n.FlushCacheEntry(context, jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName)))))
	if result {
		return C.JNI_TRUE
	} else {
		return C.JNI_FALSE
	}
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeSetRoots
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeSetRoots(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jNames C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	names, err := jutil.GoStringList(env, jutil.Object(uintptr(unsafe.Pointer(jNames))))
	if err != nil {
		jutil.JThrowV(env, err)
		return
	}
	err = n.SetRoots(names...)
	if err != nil {
		jutil.JThrowV(env, err)
	}
}

func setPermissionsArgs(env jutil.Env, jContext, jPermissions C.jobject, jName, jVersion C.jstring, jOptions C.jobject) (context *context.T, permissions access.Permissions, name, version string, options []naming.NamespaceOpt, err error) {
	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		return
	}
	err = jutil.GoVomCopy(env, jutil.Object(uintptr(unsafe.Pointer(jPermissions))), jPermissionsClass, &permissions)
	if err != nil {
		return
	}
	options, err = namespaceOptions(env, jutil.Object(uintptr(unsafe.Pointer(jOptions))))
	name = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
	version = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jVersion))))
	return
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeSetPermissions
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeSetPermissions(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring, jPermissions C.jobject, jVersion C.jstring, jOptions C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	context, permissions, name, version, options, err := setPermissionsArgs(env, jContext, jPermissions, jName, jVersion, jOptions)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	jutil.DoAsyncCall(env, jCallback, func(env jutil.Env) (jutil.Object, error) {
		return jutil.NullObject, n.SetPermissions(context, name, permissions, version, options...)
	})
}

func getPermissionsArgs(env jutil.Env, jContext C.jobject, jName C.jstring, jOptions C.jobject) (context *context.T, name string, options []naming.NamespaceOpt, err error) {
	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
	if err != nil {
		return
	}
	options, err = namespaceOptions(env, jutil.Object(uintptr(unsafe.Pointer(jOptions))))
	if err != nil {
		return
	}
	name = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
	return
}

func doGetPermissions(env jutil.Env, n namespace.T, context *context.T, name string, options []naming.NamespaceOpt) (jutil.Object, error) {
	permissions, version, err := n.GetPermissions(context, name, options...)
	if err != nil {
		return jutil.NullObject, err
	}
	jPermissions, err := jutil.JVomCopy(env, permissions, jPermissionsClass)
	if err != nil {
		return jutil.NullObject, err
	}
	result := make(map[jutil.Object]jutil.Object)
	result[jutil.JString(env, version)] = jPermissions
	return jutil.JObjectMap(env, result)
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeGetPermissions
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeGetPermissions(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring, jOptions C.jobject, jCallbackObj C.jobject) {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
	context, name, options, err := getPermissionsArgs(env, jContext, jName, jOptions)
	if err != nil {
		jutil.CallbackOnFailure(env, jCallback, err)
		return
	}
	jutil.DoAsyncCall(env, jCallback, func(env jutil.Env) (jutil.Object, error) {
		return doGetPermissions(env, n, context, name, options)
	})
}

//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeFinalize
func Java_io_v_impl_google_namespace_NamespaceImpl_nativeFinalize(jenv *C.JNIEnv, jNamespace C.jobject, goNamespacePtr C.jlong) {
	jutil.GoUnref(jutil.NativePtr(goNamespacePtr))
}
