// 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 darwin ios

package rpc

import (
	"reflect"
	"unsafe"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/options"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/vdl"
	"v.io/v23/vom"

	iutil "v.io/x/ios/util"
	icontext "v.io/x/ios/v23/context"
)

/*
#include <string.h> // memcpy
#import "types.h"
// These sizes (including C struct memory alignment/padding) isn't available from Go, so we make that available via CGo.
static const size_t sizeofSwiftByteArray = sizeof(SwiftByteArray);
static const size_t sizeofSwiftByteArrayArray = sizeof(SwiftByteArrayArray);
*/
import "C"

func doStartCall(context *context.T, name, method string, skipServerAuth bool, client rpc.Client, args []interface{}) (rpc.ClientCall, error) {
	var opts []rpc.CallOpt
	if skipServerAuth {
		opts = append(opts,
			options.NameResolutionAuthorizer{security.AllowEveryone()},
			options.ServerAuthorizer{security.AllowEveryone()})
	}
	// Invoke StartCall
	call, err := client.StartCall(context, name, method, args, opts...)
	if err != nil {
		return nil, err
	}
	return call, nil
}

// TODO From JNI, implement this for Swift
//func decodeArgs(cVomArgs C.SwiftByteArrayArray) ([]interface{}, error) {
//	if (cVomArgs == nil || cVomArgs.length == 0) {
//		return make([]interface{}, 0), nil
//	}
//	// VOM-decode each arguments into a *vdl.Value.
//	args := make([]interface{}, cVomArgs.length)
//	for i := 0; i < cVomArgs.length; i++ {
//		ret[i] = byte(*ptr)
//		ptr = (*C.jbyte)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) + unsafe.Sizeof(*ptr)))
//
//		cVomArgs
//
//		var err error
//		if args[i], err = jutil.VomDecodeToValue(vomArgs[i]); err != nil {
//			return nil, err
//		}
//	}
//	return args, nil
//}

//export ios_io_v_impl_google_rpc_ClientImpl_nativeStartCallAsync
func ios_io_v_impl_google_rpc_ClientImpl_nativeStartCallAsync(ctxHandle C.GoContextHandle, cName *C.char, cMethod *C.char, cVomArgs C.SwiftByteArrayArray, skipServerAuth bool, asyncId C.AsyncCallbackIdentifier, successCallback C.SwiftAsyncSuccessHandleCallback, failureCallback C.SwiftAsyncFailureCallback) {
	name := C.GoString(cName)
	method := C.GoString(cMethod)
	ctx := icontext.GoContext(uint64(ctxHandle))
	client := v23.GetClient(ctx)

	// TODO Get args (we don't have VOM yet in Swift so nothing to get until then)
	//	args, err := decodeArgs(env, jVomArgs)
	//	if err != nil {
	//		iutil.ThrowSwiftError(ctx, err, unsafe.Pointer(errOut))
	//		return C.GoClientCallHandle(0)
	//	}
	args := make([]interface{}, 0)

	go func() {
		result, err := doStartCall(ctx, name, method, skipServerAuth == true, client, args)
		if err != nil {
			var swiftVError C.SwiftVError
			iutil.ThrowSwiftError(ctx, err, unsafe.Pointer(&swiftVError))
			iutil.DoFailureCallback(unsafe.Pointer(failureCallback), int32(asyncId), unsafe.Pointer(&swiftVError))
		} else {
			handle := C.GoClientCallHandle(SwiftClientCall(result))
			iutil.DoSuccessHandlerCallback(unsafe.Pointer(successCallback), int32(asyncId), uint64(handle))
		}
	}()
}

//export ios_io_v_impl_google_rpc_ClientImpl_nativeClose
func ios_io_v_impl_google_rpc_ClientImpl_nativeClose(ctxHandle C.GoContextHandle) {
	ctx := icontext.GoContext(uint64(ctxHandle))
	client := v23.GetClient(ctx)
	<-client.Closed()
}

//export ios_io_v_impl_google_rpc_ClientCallImpl_nativeCloseSend
func ios_io_v_impl_google_rpc_ClientCallImpl_nativeCloseSend(ctxHandle C.GoContextHandle, callHandle C.GoClientCallHandle, errOut *C.SwiftVError) {
	ctx := icontext.GoContext(uint64(ctxHandle))
	call := GoClientCall(uint64(callHandle))
	if err := call.CloseSend(); err != nil {
		iutil.ThrowSwiftError(ctx, err, unsafe.Pointer(errOut))
		return
	}
}

func doFinish(call rpc.ClientCall, numResults int) (C.SwiftByteArrayArray, error) {
	// Have all the results be decoded into *vdl.Value.
	resultPtrs := make([]interface{}, numResults)
	for i := 0; i < numResults; i++ {
		value := new(vdl.Value)
		resultPtrs[i] = &value
	}
	if err := call.Finish(resultPtrs...); err != nil {
		// Invocation error.
		return EmptySwiftByteArrayArray(), err
	}

	// VOM-encode the results. Note in the future we'll want a pathway where we can get the original VOM results
	// from finish so we don't end up wasting CPU & memory here.

	// Prepare the byte array array that can be accessed from Swift via C.malloc
	vomResultsMemory := C.malloc(C.size_t(numResults * int(C.sizeofSwiftByteArray)))
	// Make that malloc'd memory available as a slice to Go.
	vomResultsPtrsHdr := reflect.SliceHeader{
		Data: uintptr(vomResultsMemory),
		Len:  numResults,
		Cap:  numResults,
	}
	vomResults := *(*[]C.SwiftByteArray)(unsafe.Pointer(&vomResultsPtrsHdr))
	// Create the C Struct to return that encapsulates our byte array array
	var cVomResults C.SwiftByteArrayArray
	cVomResults.length = C._GoUint64(numResults)
	cVomResults.data = (*C.SwiftByteArray)(vomResultsMemory)

	// For each result, VOM encode into a byte array that we stick into the returned struct
	for i, resultPtr := range resultPtrs {
		// Remove the pointer from the result.  Simply *resultPtr doesn't work
		// as resultPtr is of type interface{}.
		result := interface{}(iutil.DerefOrDie(resultPtr))
		var vomResult []byte
		var err error
		if vomResult, err = vom.Encode(result); err != nil {
			return EmptySwiftByteArrayArray(), err
		}
		cVomResultCopy := C.malloc(C.size_t(len(vomResult)))
		C.memcpy(cVomResultCopy, unsafe.Pointer(&vomResult[0]), C.size_t(len(vomResult)))
		var cVomResult C.SwiftByteArray
		cVomResult.length = C._GoUint64(len(vomResult))
		cVomResult.data = (*C.char)(cVomResultCopy)
		vomResults[i] = cVomResult
	}
	return cVomResults, nil
}

//export ios_io_v_impl_google_rpc_ClientCallImpl_nativeFinishAsync
func ios_io_v_impl_google_rpc_ClientCallImpl_nativeFinishAsync(ctxHandle C.GoContextHandle, callHandle C.GoClientCallHandle, numResults int, asyncId C.AsyncCallbackIdentifier, successCallback C.SwiftAsyncSuccessByteArrayArrayCallback, failureCallback C.SwiftAsyncFailureCallback) {
	ctx := icontext.GoContext(uint64(ctxHandle))
	call := GoClientCall(uint64(callHandle))
	go func() {
		result, err := doFinish(call, numResults)
		if err != nil {
			var swiftVError C.SwiftVError
			iutil.ThrowSwiftError(ctx, err, unsafe.Pointer(&swiftVError))
			iutil.DoFailureCallback(unsafe.Pointer(failureCallback), int32(asyncId), unsafe.Pointer(&swiftVError))
		} else {
			iutil.DoSuccessByteArrayArrayCallback(unsafe.Pointer(successCallback), int32(asyncId), unsafe.Pointer(&result))
		}
	}()
}

//export ios_io_v_impl_google_rpc_ClientCallImpl_nativeFinalize
func ios_io_v_impl_google_rpc_ClientCallImpl_nativeFinalize(callHandle C.GoClientCallHandle) {
	iutil.GoUnref(uint64(callHandle))
}
