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

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;
}
