// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// C support functions for bindings. This file is copied into the
// generated gomobile_bind package and compiled along with the
// generated binding files.

#include <android/log.h>
#include <errno.h>
#include <jni.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "seq.h"
#include "_cgo_export.h"

#define NULL_REFNUM 41

// initClasses are only exported from Go if reverse bindings are used.
// If they're not, weakly define a no-op function.
__attribute__((weak)) void initClasses(void) { }

static JavaVM *jvm;
// jnienvs holds the per-thread JNIEnv* for Go threads where we called AttachCurrentThread.
// A pthread key destructor is supplied to call DetachCurrentThread on exit. This trick is
// documented in http://developer.android.com/training/articles/perf-jni.html under "Threads".
static pthread_key_t jnienvs;

static jclass seq_class;
static jmethodID seq_getRef;
static jmethodID seq_decRef;
static jmethodID seq_incRef;
static jmethodID seq_incGoObjectRef;
static jmethodID seq_incRefnum;

static jfieldID ref_objField;

static jclass throwable_class;

// env_destructor is registered as a thread data key destructor to
// clean up a Go thread that is attached to the JVM.
static void env_destructor(void *env) {
	if ((*jvm)->DetachCurrentThread(jvm) != JNI_OK) {
		LOG_INFO("failed to detach current thread");
	}
}

static JNIEnv *go_seq_get_thread_env(void) {
	JNIEnv *env;
	jint ret = (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_6);
	if (ret != JNI_OK) {
		if (ret != JNI_EDETACHED) {
			LOG_FATAL("failed to get thread env");
		}
		if ((*jvm)->AttachCurrentThread(jvm, &env, NULL) != JNI_OK) {
			LOG_FATAL("failed to attach current thread");
		}
		pthread_setspecific(jnienvs, env);
	}
	return env;
}

void go_seq_maybe_throw_exception(JNIEnv *env, jobject exc) {
	if (exc != NULL) {
		(*env)->Throw(env, exc);
	}
}

jobject go_seq_get_exception(JNIEnv *env) {
	jthrowable exc = (*env)->ExceptionOccurred(env);
	if (!exc) {
		return NULL;
	}
	(*env)->ExceptionClear(env);
	return exc;
}

jbyteArray go_seq_to_java_bytearray(JNIEnv *env, nbyteslice s, int copy) {
	if (s.ptr == NULL) {
		return NULL;
	}
	jbyteArray res = (*env)->NewByteArray(env, s.len);
	if (res == NULL) {
		LOG_FATAL("NewByteArray failed");
	}
	(*env)->SetByteArrayRegion(env, res, 0, s.len, s.ptr);
	if (copy) {
		free(s.ptr);
	}
	return res;
}

#define surr1 0xd800
#define surr2 0xdc00
#define surr3 0xe000

// Unicode replacement character
#define replacementChar 0xFFFD

#define rune1Max ((1<<7) - 1)
#define rune2Max ((1<<11) - 1)
#define rune3Max ((1<<16) - 1)
// Maximum valid Unicode code point.
#define MaxRune 0x0010FFFF

#define surrogateMin 0xD800
#define surrogateMax 0xDFFF
// 0011 1111
#define maskx 0x3F
// 1000 0000
#define tx 0x80
// 1100 0000
#define t2 0xC0
// 1110 0000
#define t3 0xE0
// 1111 0000
#define t4 0xF0

// encode_rune writes into p (which must be large enough) the UTF-8 encoding
// of the rune. It returns the number of bytes written.
static int encode_rune(uint8_t *p, uint32_t r) {
	if (r <= rune1Max) {
		p[0] = (uint8_t)r;
		return 1;
	} else if (r <= rune2Max) {
		p[0] = t2 | (uint8_t)(r>>6);
		p[1] = tx | (((uint8_t)(r))&maskx);
		return 2;
	} else {
		if (r > MaxRune || (surrogateMin <= r && r <= surrogateMax)) {
			r = replacementChar;
		}
		if (r <= rune3Max) {
			p[0] = t3 | (uint8_t)(r>>12);
			p[1] = tx | (((uint8_t)(r>>6))&maskx);
			p[2] = tx | (((uint8_t)(r))&maskx);
			return 3;
		} else {
			p[0] = t4 | (uint8_t)(r>>18);
			p[1] = tx | (((uint8_t)(r>>12))&maskx);
			p[2] = tx | (((uint8_t)(r>>6))&maskx);
			p[3] = tx | (((uint8_t)(r))&maskx);
			return 4;
		}
	}
}

// utf16_decode decodes an array of UTF16 characters to a UTF-8 encoded
// nstring copy. The support functions and utf16_decode itself are heavily
// based on the unicode/utf8 and unicode/utf16 Go packages.
static nstring utf16_decode(jchar *chars, jsize len) {
	jsize worstCaseLen = 4*len;
	uint8_t *buf = malloc(worstCaseLen);
	if (buf == NULL) {
		LOG_FATAL("utf16Decode: malloc failed");
	}
	jsize nsrc = 0;
	jsize ndst = 0;
	while (nsrc < len) {
		uint32_t r = chars[nsrc];
		nsrc++;
		if (surr1 <= r && r < surr2 && nsrc < len) {
			uint32_t r2 = chars[nsrc];
			if (surr2 <= r2 && r2 < surr3) {
				nsrc++;
				r = (((r-surr1)<<10) | (r2 - surr2)) + 0x10000;
			}
		}
		if (ndst + 4 > worstCaseLen) {
			LOG_FATAL("utf16Decode: buffer overflow");
		}
		ndst += encode_rune(buf + ndst, r);
	}
	struct nstring res = {.chars = buf, .len = ndst};
	return res;
}

nstring go_seq_from_java_string(JNIEnv *env, jstring str) {
	struct nstring res = {NULL, 0};
	if (str == NULL) {
		return res;
	}
	jsize nchars = (*env)->GetStringLength(env, str);
	if (nchars == 0) {
		return res;
	}
	jchar *chars = (jchar *)(*env)->GetStringChars(env, str, NULL);
	if (chars == NULL) {
		LOG_FATAL("GetStringChars failed");
	}
	nstring nstr = utf16_decode(chars, nchars);
	(*env)->ReleaseStringChars(env, str, chars);
	return nstr;
}

nbyteslice go_seq_from_java_bytearray(JNIEnv *env, jbyteArray arr, int copy) {
	struct nbyteslice res = {NULL, 0};
	if (arr == NULL) {
		return res;
	}

	jsize len = (*env)->GetArrayLength(env, arr);
	if (len == 0) {
		return res;
	}
	jbyte *ptr = (*env)->GetByteArrayElements(env, arr, NULL);
	if (ptr == NULL) {
		LOG_FATAL("GetByteArrayElements failed");
	}
	if (copy) {
		void *ptr_copy = (void *)malloc(len);
		if (ptr_copy == NULL) {
			LOG_FATAL("malloc failed");
		}
		memcpy(ptr_copy, ptr, len);
		(*env)->ReleaseByteArrayElements(env, arr, ptr, JNI_ABORT);
		ptr = (jbyte *)ptr_copy;
	}
	res.ptr = ptr;
	res.len = len;
	return res;
}

int32_t go_seq_to_refnum_go(JNIEnv *env, jobject o) {
	if (o == NULL) {
		return NULL_REFNUM;
	}
	return (int32_t)(*env)->CallStaticIntMethod(env, seq_class, seq_incGoObjectRef, o);
}

int32_t go_seq_to_refnum(JNIEnv *env, jobject o) {
	if (o == NULL) {
		return NULL_REFNUM;
	}
	return (int32_t)(*env)->CallStaticIntMethod(env, seq_class, seq_incRef, o);
}

int32_t go_seq_unwrap(jint refnum) {
	JNIEnv *env = go_seq_push_local_frame(0);
	jobject jobj = go_seq_from_refnum(env, refnum, NULL, NULL);
	int32_t goref = go_seq_to_refnum_go(env, jobj);
	go_seq_pop_local_frame(env);
	return goref;
}

jobject go_seq_from_refnum(JNIEnv *env, int32_t refnum, jclass proxy_class, jmethodID proxy_cons) {
	if (refnum == NULL_REFNUM) {
		return NULL;
	}
	// Seq.Ref ref = Seq.getRef(refnum)
	jobject ref = (*env)->CallStaticObjectMethod(env, seq_class, seq_getRef, (jint)refnum);
	if (ref == NULL) {
		LOG_FATAL("Unknown reference: %d", refnum);
	}
	if (refnum > 0) { // Java object
		// Go incremented the reference count just before passing the refnum. Decrement it here.
		(*env)->CallStaticVoidMethod(env, seq_class, seq_decRef, (jint)refnum);
		// return ref.obj
		return (*env)->GetObjectField(env, ref, ref_objField);
	} else if (proxy_class != NULL) {
		// return new <Proxy>(ref)
		return (*env)->NewObject(env, proxy_class, proxy_cons, ref);
	} else {
		// We're inside a Java proxy constructor and only need the Seq.Ref
		return ref;
	}
}

// go_seq_to_java_string converts a nstring to a jstring.
jstring go_seq_to_java_string(JNIEnv *env, nstring str) {
	jstring s = (*env)->NewString(env, str.chars, str.len/2);
	if (str.chars != NULL) {
		free(str.chars);
	}
	return s;
}

// go_seq_push_local_frame retrieves or creates the JNIEnv* for the current thread
// and pushes a JNI reference frame. Must be matched with call to go_seq_pop_local_frame.
JNIEnv *go_seq_push_local_frame(jint nargs) {
	JNIEnv *env = go_seq_get_thread_env();
	// Given the number of function arguments, compute a conservative bound for the minimal frame size.
	// Assume two slots for each per parameter (Seq.Ref and Seq.Object) and add extra
	// extra space for the receiver, the return value, and exception (if any).
	jint frameSize = 2*nargs + 10;
	if ((*env)->PushLocalFrame(env, frameSize) < 0) {
		LOG_FATAL("PushLocalFrame failed");
	}
	return env;
}

// Pop the current local frame, freeing all JNI local references in it
void go_seq_pop_local_frame(JNIEnv *env) {
	(*env)->PopLocalFrame(env, NULL);
}

void go_seq_inc_ref(int32_t ref) {
	JNIEnv *env = go_seq_get_thread_env();
	(*env)->CallStaticVoidMethod(env, seq_class, seq_incRefnum, (jint)ref);
}

void go_seq_dec_ref(int32_t ref) {
	JNIEnv *env = go_seq_get_thread_env();
	(*env)->CallStaticVoidMethod(env, seq_class, seq_decRef, (jint)ref);
}

JNIEXPORT void JNICALL
Java_go_Seq_init(JNIEnv *env, jclass clazz) {
	if ((*env)->GetJavaVM(env, &jvm) != 0) {
		LOG_FATAL("failed to get JVM");
	}
	if (pthread_key_create(&jnienvs, env_destructor) != 0) {
		LOG_FATAL("failed to initialize jnienvs thread local storage");
	}

	seq_class = (*env)->NewGlobalRef(env, clazz);
	seq_getRef = (*env)->GetStaticMethodID(env, seq_class, "getRef", "(I)Lgo/Seq$Ref;");
	if (seq_getRef == NULL) {
		LOG_FATAL("failed to find method Seq.getRef");
	}
	seq_decRef = (*env)->GetStaticMethodID(env, seq_class, "decRef", "(I)V");
	if (seq_decRef == NULL) {
		LOG_FATAL("failed to find method Seq.decRef");
	}
	seq_incRefnum = (*env)->GetStaticMethodID(env, seq_class, "incRefnum", "(I)V");
	if (seq_incRefnum == NULL) {
		LOG_FATAL("failed to find method Seq.incRefnum");
	}
	seq_incRef = (*env)->GetStaticMethodID(env, seq_class, "incRef", "(Ljava/lang/Object;)I");
	if (seq_incRef == NULL) {
		LOG_FATAL("failed to find method Seq.incRef");
	}
	seq_incGoObjectRef = (*env)->GetStaticMethodID(env, seq_class, "incGoObjectRef", "(Lgo/Seq$GoObject;)I");
	if (seq_incGoObjectRef == NULL) {
		LOG_FATAL("failed to find method Seq.incGoObjectRef");
	}
	jclass ref_class = (*env)->FindClass(env, "go/Seq$Ref");
	if (ref_class == NULL) {
		LOG_FATAL("failed to find the Seq.Ref class");
	}
	ref_objField = (*env)->GetFieldID(env, ref_class, "obj", "Ljava/lang/Object;");
	if (ref_objField == NULL) {
		LOG_FATAL("failed to find the Seq.Ref.obj field");
	}
	initClasses();
}

JNIEXPORT void JNICALL
Java_go_Seq_destroyRef(JNIEnv *env, jclass clazz, jint refnum) {
	DestroyRef(refnum);
}

JNIEXPORT void JNICALL
Java_go_Seq_incGoRef(JNIEnv *env, jclass clazz, jint refnum) {
	IncGoRef(refnum);
}

jclass go_seq_find_class(const char *name) {
	JNIEnv *env = go_seq_push_local_frame(0);
	jclass clazz = (*env)->FindClass(env, name);
	if (clazz == NULL) {
		(*env)->ExceptionClear(env);
	} else {
		clazz = (*env)->NewGlobalRef(env, clazz);
	}
	go_seq_pop_local_frame(env);
	return clazz;
}

jmethodID go_seq_get_static_method_id(jclass clazz, const char *name, const char *sig) {
	JNIEnv *env = go_seq_push_local_frame(0);
	jmethodID m = (*env)->GetStaticMethodID(env, clazz, name, sig);
	if (m == NULL) {
		(*env)->ExceptionClear(env);
	}
	go_seq_pop_local_frame(env);
	return m;
}

jmethodID go_seq_get_method_id(jclass clazz, const char *name, const char *sig) {
	JNIEnv *env = go_seq_push_local_frame(0);
	jmethodID m = (*env)->GetMethodID(env, clazz, name, sig);
	if (m == NULL) {
		(*env)->ExceptionClear(env);
	}
	go_seq_pop_local_frame(env);
	return m;
}

void go_seq_release_byte_array(JNIEnv *env, jbyteArray arr, jbyte* ptr) {
	if (ptr != NULL) {
		(*env)->ReleaseByteArrayElements(env, arr, ptr, 0);
	}
}

int go_seq_isinstanceof(jint refnum, jclass clazz) {
	JNIEnv *env = go_seq_push_local_frame(0);
	jobject obj = go_seq_from_refnum(env, refnum, NULL, NULL);
	jboolean isinst = (*env)->IsInstanceOf(env, obj, clazz);
	go_seq_pop_local_frame(env);
	return isinst;
}
