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

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"unsafe"

	"v.io/v23"
	"v.io/v23/security/access"
	"v.io/x/ref/services/mounttable/mounttablelib"

	"v.io/v23/options"
	jrpc "v.io/x/jni/impl/google/rpc"
	jutil "v.io/x/jni/util"
	jcontext "v.io/x/jni/v23/context"
	jaccess "v.io/x/jni/v23/security/access"
)

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

var (
	permissionsSign = jutil.ClassSign("io.v.v23.security.access.Permissions")
	contextSign     = jutil.ClassSign("io.v.v23.context.VContext")
	serverSign      = jutil.ClassSign("io.v.v23.rpc.Server")

	jVRuntimeImplClass jutil.Class
)

// Init initializes the JNI code with the given Java environment.  This method
// must be invoked before any other method in this package and must be called
// from the main Java thread (e.g., On_Load()).
func Init(env jutil.Env) error {
	var err error
	jVRuntimeImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rt/VRuntimeImpl")
	if err != nil {
		return err
	}
	return nil
}

//export Java_io_v_impl_google_services_mounttable_MountTableServer_nativeWithNewServer
func Java_io_v_impl_google_services_mounttable_MountTableServer_nativeWithNewServer(jenv *C.JNIEnv, jMountTableServerClass C.jclass, jContext C.jobject, jMountTableServerParams C.jobject) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext)))
	jParams := jutil.Object(uintptr(unsafe.Pointer(jMountTableServerParams)))

	// Read and translate all of the server params.
	mountName, err := jutil.CallStringMethod(env, jParams, "getName", nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	rootDir, err := jutil.CallStringMethod(env, jParams, "getStorageRootDir", nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	if rootDir == "" {
		rootDir = filepath.Join(os.TempDir(), "mounttable")
		if err := os.Mkdir(rootDir, 0755); err != nil && !os.IsExist(err) {
			jutil.JThrowV(env, err)
			return nil
		}
	}
	permsJMap, err := jutil.CallMapMethod(env, jParams, "getPermissions", nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	permsMap := make(map[string]access.Permissions)
	for jPath, jPerms := range permsJMap {
		path := jutil.GoString(env, jPath)
		perms, err := jaccess.GoPermissions(env, jPerms)
		if err != nil {
			jutil.JThrowV(env, err)
			return nil
		}
		permsMap[path] = perms
	}
	// Write JSON-encoded permissions to a file.
	jsonPerms, err := json.Marshal(permsMap)
	if err != nil {
		jutil.JThrowV(env, fmt.Errorf("Couldn't JSON-encode path-permissions: %v", err))
		return nil

	}
	permsFile, err := ioutil.TempFile(rootDir, "jni_permissions")
	if err != nil {
		jutil.JThrowV(env, fmt.Errorf("Couldn't create permissions file: %v", err))
		return nil
	}
	w := bufio.NewWriter(permsFile)
	if _, err := w.Write(jsonPerms); err != nil {
		jutil.JThrowV(env, fmt.Errorf("Couldn't write to permissions file: %v", err))
		return nil
	}
	if err := w.Flush(); err != nil {
		jutil.JThrowV(env, fmt.Errorf("Couldn't flush to permissions file: %v", err))
	}
	statsPrefix, err := jutil.CallStringMethod(env, jParams, "getStatsPrefix", nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}

	// Start the mounttable server.
	ctx, err := jcontext.GoContext(env, jCtx)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	d, err := mounttablelib.NewMountTableDispatcher(ctx, permsFile.Name(), rootDir, statsPrefix)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	newCtx, s, err := v23.WithNewDispatchingServer(ctx, mountName, d, options.ServesMountTable(true))
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	jNewCtx, err := jcontext.JavaContext(env, newCtx)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	jServer, err := jrpc.JavaServer(env, s)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	// Attach a server to the new context.
	jServerAttCtx, err := jutil.CallStaticObjectMethod(env, jVRuntimeImplClass, "withServer", []jutil.Sign{contextSign, serverSign}, contextSign, jNewCtx, jServer)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jServerAttCtx))
}
