// 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 <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_throw_exc;
static jmethodID seq_getRef;
static jmethodID seq_decRef;
static jmethodID seq_incRef;
static jmethodID seq_incRefnum;
static jmethodID seq_wrapThrowable;

static jmethodID throwable_getMessage;

static jfieldID ref_objField;

// 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 msg) {
	if (msg != NULL) {
		(*env)->CallStaticVoidMethod(env, seq_class, seq_throw_exc, msg);
	}
}

jobject go_seq_wrap_exception(JNIEnv *env) {
	jthrowable exc = (*env)->ExceptionOccurred(env);
	if (!exc) {
		return NULL;
	}
	(*env)->ExceptionClear(env);
	return (*env)->CallStaticObjectMethod(env, seq_class, seq_wrapThrowable, 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(JNIEnv *env, jobject o) {
	if (o == NULL) {
		return NULL_REFNUM;
	}
	return (int32_t)(*env)->CallStaticIntMethod(env, seq_class, seq_incRef, o);
}

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 {
		// return new <Proxy>(ref)
		return (*env)->NewObject(env, proxy_class, proxy_cons, 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 cap) {
	JNIEnv *env = go_seq_get_thread_env();
	if ((*env)->PushLocalFrame(env, cap) < 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_throw_exc = (*env)->GetStaticMethodID(env, seq_class, "throwException", "(Lgo/Universe$error;)V");
	if (seq_throw_exc == NULL) {
		LOG_FATAL("failed to find method Seq.throwException");
	}

	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_wrapThrowable = (*env)->GetStaticMethodID(env, seq_class, "wrapThrowable", "(Ljava/lang/Throwable;)Lgo/Universe$error;");
	if (seq_wrapThrowable == NULL) {
		LOG_FATAL("failed to find method Seq.wrapThrowable");
	}
	jclass throwable_class = (*env)->FindClass(env, "java/lang/Throwable");
	if (throwable_class == NULL) {
		LOG_FATAL("failed to find Throwable class");
	}
	throwable_getMessage = (*env)->GetMethodID(env, throwable_class, "getMessage", "()Ljava/lang/String;");
	if (throwable_getMessage == NULL) {
		LOG_FATAL("failed to find method Throwable.getMessage");
	}
	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");
	}
}

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