/*******************************************************************************
 * Copyright (c) 2006, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 * 	   Andrew Niefer
 *******************************************************************************/
 
#include "eclipseJNI.h"
#include "eclipseCommon.h"
#include "eclipseOS.h"
#include "eclipseShm.h"

#include <stdlib.h>
#include <string.h>


static _TCHAR* failedToLoadLibrary = _T_ECLIPSE("Failed to load the JNI shared library \"%s\".\n");
static _TCHAR* createVMSymbolNotFound = _T_ECLIPSE("The JVM shared library \"%s\"\ndoes not contain the JNI_CreateJavaVM symbol.\n");
static _TCHAR* failedCreateVM = _T_ECLIPSE("Failed to create the Java Virtual Machine.\n");
static _TCHAR* internalExpectedVMArgs = _T_ECLIPSE("Internal Error, the JVM argument list is empty.\n");
static _TCHAR* mainClassNotFound = _T_ECLIPSE("Failed to find a Main Class in \"%s\".\n");

static JNINativeMethod natives[] = {{"_update_splash", "()V", (void *)&update_splash},
									{"_get_splash_handle", "()J", (void *)&get_splash_handle},
									{"_set_exit_data", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)&set_exit_data},
									{"_set_launcher_info", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)&set_launcher_info},
									{"_show_splash", "(Ljava/lang/String;)V", (void *)&show_splash},
									{"_takedown_splash", "()V", (void *)&takedown_splash},
									{"_get_os_recommended_folder", "()Ljava/lang/String;", (void *)&get_os_recommended_folder}};

/* local methods */
static jstring newJavaString(JNIEnv *env, _TCHAR * str);
static void registerNatives(JNIEnv *env);
static int shouldShutdown(JNIEnv *env);
static void JNI_ReleaseStringChars(JNIEnv *env, jstring s, const _TCHAR* data);
static const _TCHAR* JNI_GetStringChars(JNIEnv *env, jstring str);
static char * getMainClass(JNIEnv *env, _TCHAR * jarFile);
static void setLibraryLocation(JNIEnv *env, jobject obj);

static JavaVM * jvm = 0;
static JNIEnv *env = 0;

/* cache String class and methods to avoid looking them up all the time */
static jclass string_class = NULL;
#if !defined(UNICODE) && !defined(MACOSX)
static jmethodID string_getBytesMethod = NULL;
static jmethodID string_ctor = NULL;
#endif

/* JNI Callback methods */
JNIEXPORT void JNICALL set_exit_data(JNIEnv * env, jobject obj, jstring id, jstring s){
	const _TCHAR* data = NULL;
	const _TCHAR* sharedId = NULL;
	size_t length;
	 
	if(s != NULL) {
		length = (*env)->GetStringLength(env, s);
		if(!(*env)->ExceptionOccurred(env)) {
			data = JNI_GetStringChars(env, s);
			if (data != NULL) {
				if(id != NULL) {
					sharedId = JNI_GetStringChars(env, id);
					if(sharedId != NULL) {
						setSharedData(sharedId, data);
						JNI_ReleaseStringChars(env, id, sharedId);
					}
				} else {
					exitData = malloc((length + 1) * sizeof(_TCHAR*));
					_tcsncpy( exitData, data, length);
					exitData[length] = _T_ECLIPSE('\0');
				}
				JNI_ReleaseStringChars(env, s, data);
			}
		}
		if(data == NULL && sharedId == NULL) {
			(*env)->ExceptionDescribe(env);
			(*env)->ExceptionClear(env);
		}
	}
}

JNIEXPORT void JNICALL set_launcher_info(JNIEnv * env, jobject obj, jstring launcher, jstring name){
	const _TCHAR* launcherPath = NULL;
	const _TCHAR* launcherName = NULL;
	
	if (launcher != NULL) {
		launcherPath = JNI_GetStringChars(env, launcher);
		if (launcherPath != NULL) {
			setProgramPath(_tcsdup(launcherPath));
			JNI_ReleaseStringChars(env, launcher, launcherPath);
		}
	}
	
	if (name != NULL) {
		launcherName = JNI_GetStringChars(env, name);
		if (launcherName != NULL) {
			setOfficialName(_tcsdup(launcherName));
			JNI_ReleaseStringChars(env, name, launcherName);
		}
	}
}


JNIEXPORT void JNICALL update_splash(JNIEnv * env, jobject obj){
	dispatchMessages();
}

JNIEXPORT jlong JNICALL get_splash_handle(JNIEnv * env, jobject obj){
	return getSplashHandle();
}

JNIEXPORT void JNICALL show_splash(JNIEnv * env, jobject obj, jstring s){
	const _TCHAR* data = NULL;
	
	setLibraryLocation(env, obj);
	
	if(s != NULL) {
		data = JNI_GetStringChars(env, s);
		if(data != NULL) {
			showSplash(data);
			JNI_ReleaseStringChars(env, s, data);
		} else {
			(*env)->ExceptionDescribe(env);
			(*env)->ExceptionClear(env);
		}
	}
}

JNIEXPORT void JNICALL takedown_splash(JNIEnv * env, jobject obj){
	takeDownSplash();
}

JNIEXPORT jstring JNICALL get_os_recommended_folder(JNIEnv * env, jobject obj){
#ifdef MACOSX
	return newJavaString(env, getFolderForApplicationData());
#else
	return NULL;
#endif
}

/*
 * On AIX we need the location of the eclipse shared library so that we
 * can find the libeclipse-motif.so library.  Reach into the JNIBridge
 * object to get the "library" field.
 */
static void setLibraryLocation(JNIEnv * env, jobject obj) {
	jclass bridge = (*env)->FindClass(env, "org/eclipse/equinox/launcher/JNIBridge");
	if (bridge != NULL) {
		jfieldID libraryField = (*env)->GetFieldID(env, bridge, "library", "Ljava/lang/String;");
		if (libraryField != NULL) {
			jstring stringObject = (jstring) (*env)->GetObjectField(env, obj, libraryField);
			if (stringObject != NULL) {
				const _TCHAR * str = JNI_GetStringChars(env, stringObject);
				eclipseLibrary = _tcsdup(str);
				JNI_ReleaseStringChars(env, stringObject, str);
			}
		}
	}
	if( (*env)->ExceptionOccurred(env) != 0 ){
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
}

static void registerNatives(JNIEnv *env) {
	jclass bridge = (*env)->FindClass(env, "org/eclipse/equinox/launcher/JNIBridge");
	if(bridge != NULL) {
		int numNatives = sizeof(natives) / sizeof(natives[0]);
		(*env)->RegisterNatives(env, bridge, natives, numNatives);	
	}
	if( (*env)->ExceptionOccurred(env) != 0 ){
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
}


/* Get a _TCHAR* from a jstring, string should be released later with JNI_ReleaseStringChars */
static const _TCHAR * JNI_GetStringChars(JNIEnv *env, jstring str) {
	const _TCHAR * result = NULL;
#ifdef UNICODE
	/* GetStringChars is not null terminated, make a copy */
	const _TCHAR * stringChars = (*env)->GetStringChars(env, str, 0);
	int length = (*env)->GetStringLength(env, str);
	_TCHAR * copy = malloc( (length + 1) * sizeof(_TCHAR));
	_tcsncpy(copy, stringChars, length);
	copy[length] = _T_ECLIPSE('\0');
	(*env)->ReleaseStringChars(env, str, stringChars);
	result = copy;
#elif MACOSX
	/* Use UTF on the Mac */
	result = (*env)->GetStringUTFChars(env, str, 0);
#else
	/* Other platforms, use java's default encoding */ 
	_TCHAR* buffer = NULL;
	if (string_class == NULL)
		string_class = (*env)->FindClass(env, "java/lang/String");
	if (string_class != NULL) {
		if (string_getBytesMethod == NULL)
			string_getBytesMethod = (*env)->GetMethodID(env, string_class, "getBytes", "()[B");
		if (string_getBytesMethod != NULL) {
			jbyteArray bytes = (*env)->CallObjectMethod(env, str, string_getBytesMethod);
			if (!(*env)->ExceptionOccurred(env)) {
				jsize length = (*env)->GetArrayLength(env, bytes);
				buffer = malloc( (length + 1) * sizeof(_TCHAR*));
				(*env)->GetByteArrayRegion(env, bytes, 0, length, (jbyte*)buffer);
				buffer[length] = 0;
			}
			(*env)->DeleteLocalRef(env, bytes);
		}
	}
	if(buffer == NULL) {
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
	result = buffer;
#endif
	return result;
}

/* Release the string that was obtained using JNI_GetStringChars */
static void JNI_ReleaseStringChars(JNIEnv *env, jstring s, const _TCHAR* data) {
#ifdef UNICODE
	free((_TCHAR*)data);
#elif MACOSX
	(*env)->ReleaseStringUTFChars(env, s, data);
#else
	free((_TCHAR*)data);
#endif
}

static jstring newJavaString(JNIEnv *env, _TCHAR * str)
{
	jstring newString = NULL;
#ifdef UNICODE
	size_t length = _tcslen(str);
	newString = (*env)->NewString(env, str, length);
#elif MACOSX
	newString = (*env)->NewStringUTF(env, str);
#else
	size_t length = _tcslen(str);
	jbyteArray bytes = (*env)->NewByteArray(env, length);
	if(bytes != NULL) {
		(*env)->SetByteArrayRegion(env, bytes, 0, length, (jbyte *)str);
		if (!(*env)->ExceptionOccurred(env)) {
			if (string_class == NULL)
				string_class = (*env)->FindClass(env, "java/lang/String");
			if(string_class != NULL) {
				if (string_ctor == NULL)
					string_ctor = (*env)->GetMethodID(env, string_class, "<init>",  "([B)V");
				if(string_ctor != NULL) {
					newString = (*env)->NewObject(env, string_class, string_ctor, bytes);
				}
			}
		}
		(*env)->DeleteLocalRef(env, bytes);
	}
#endif
	if(newString == NULL) {
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
	return newString;
}

static jobjectArray createRunArgs( JNIEnv *env, _TCHAR * args[] ) {
	int index = 0, length = -1;
	jobjectArray stringArray = NULL;
	jstring string;
	
	/*count the number of elements first*/
	while(args[++length] != NULL);
	
	if (string_class == NULL)
		string_class = (*env)->FindClass(env, "java/lang/String");
	if(string_class != NULL) {
		stringArray = (*env)->NewObjectArray(env, length, string_class, 0);
		if(stringArray != NULL) {
			for( index = 0; index < length; index++) {
				string = newJavaString(env, args[index]);
				if(string != NULL) {
					(*env)->SetObjectArrayElement(env, stringArray, index, string); 
					(*env)->DeleteLocalRef(env, string);
				} else {
					(*env)->DeleteLocalRef(env, stringArray);
					(*env)->ExceptionDescribe(env);
					(*env)->ExceptionClear(env);
					return NULL;
				}
			}
		}
	} 
	if(stringArray == NULL) {
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
	return stringArray;
}
					 
JavaResults * startJavaJNI( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile )
{
	int i;
	int numVMArgs = -1;
	void * jniLibrary;
	JNI_createJavaVM createJavaVM;
	JavaVMInitArgs init_args;
	JavaVMOption * options;
	char * mainClassName = NULL;
	JavaResults * results = NULL;
	
	/* JNI reflection */
	jclass mainClass = NULL;			/* The Main class to load */
	jmethodID mainConstructor = NULL;	/* Main's default constructor Main() */
	jobject mainObject = NULL;			/* An instantiation of the main class */
	jmethodID runMethod = NULL;			/* Main.run(String[]) */
	jobjectArray methodArgs = NULL;		/* Arguments to pass to run */
	
	results = malloc(sizeof(JavaResults));
	memset(results, 0, sizeof(JavaResults));
	
	jniLibrary = loadLibrary(libPath);
	if(jniLibrary == NULL) {
		results->launchResult = -1;
		results->errorMessage = malloc((_tcslen(failedToLoadLibrary) + _tcslen(libPath) + 1) * sizeof(_TCHAR));
		_stprintf(results->errorMessage, failedToLoadLibrary, libPath);
		return results; /*error*/
	}

	createJavaVM = (JNI_createJavaVM)findSymbol(jniLibrary, _T_ECLIPSE("JNI_CreateJavaVM"));
	if(createJavaVM == NULL) {
		results->launchResult = -2;
		results->errorMessage = malloc((_tcslen(createVMSymbolNotFound) + _tcslen(libPath) + 1) * sizeof(_TCHAR));
		_stprintf(results->errorMessage, createVMSymbolNotFound, libPath);
		return results; /*error*/
	}
	
	/* count the vm args */
	while(vmArgs[++numVMArgs] != NULL) {}
	
	if(numVMArgs <= 0) {
		/*error, we expect at least the required vm arg */
		results->launchResult = -3;
		results->errorMessage = _tcsdup(internalExpectedVMArgs);
		return results;
	}
	
	options = malloc(numVMArgs * sizeof(JavaVMOption));
	for(i = 0; i < numVMArgs; i++){
		options[i].optionString = toNarrow(vmArgs[i]);
		options[i].extraInfo = 0;
	}
		
#ifdef MACOSX
	init_args.version = JNI_VERSION_1_4;
#else		
	init_args.version = JNI_VERSION_1_2;
#endif
	init_args.options = options;
	init_args.nOptions = numVMArgs;
	init_args.ignoreUnrecognized = JNI_TRUE;
	
	if( createJavaVM(&jvm, &env, &init_args) == 0 ) {
		registerNatives(env);
		
		mainClassName = getMainClass(env, jarFile);
		if (mainClassName != NULL) {
			mainClass = (*env)->FindClass(env, mainClassName);
			free(mainClassName);
		}
		
		if (mainClass == NULL) {
			if ((*env)->ExceptionOccurred(env)) {
				(*env)->ExceptionDescribe(env);
				(*env)->ExceptionClear(env);
			}
			mainClass = (*env)->FindClass(env, "org/eclipse/equinox/launcher/Main");
		}	

		if(mainClass != NULL) {
			results->launchResult = -6; /* this will be reset to 0 below on success */
			mainConstructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V");
			if(mainConstructor != NULL) {
				mainObject = (*env)->NewObject(env, mainClass, mainConstructor);
				if(mainObject != NULL) {
					runMethod = (*env)->GetMethodID(env, mainClass, "run", "([Ljava/lang/String;)I");
					if(runMethod != NULL) {
						methodArgs = createRunArgs(env, progArgs);
						if(methodArgs != NULL) {
							results->launchResult = 0;
							results->runResult = (*env)->CallIntMethod(env, mainObject, runMethod, methodArgs);
							(*env)->DeleteLocalRef(env, methodArgs);
						}
					}
					(*env)->DeleteLocalRef(env, mainObject);
				}
			}
		} else {
			results->launchResult = -5;
			results->errorMessage = malloc((_tcslen(mainClassNotFound) + _tcslen(jarFile) + 1) * sizeof(_TCHAR));
			_stprintf(results->errorMessage, mainClassNotFound, jarFile);
		}
		if((*env)->ExceptionOccurred(env)){
			(*env)->ExceptionDescribe(env);
			(*env)->ExceptionClear(env);
		}
		
	} else {
		results->launchResult = -4;
		results->errorMessage = _tcsdup(failedCreateVM);
	}

	/* toNarrow allocated new strings, free them */
	for(i = 0; i < numVMArgs; i++){
		free( options[i].optionString );
	}
	free(options);
	return results;
}

static char * getMainClass(JNIEnv *env, _TCHAR * jarFile) {
	jclass jarFileClass = NULL, manifestClass = NULL, attributesClass = NULL;
	jmethodID jarFileConstructor = NULL, getManifestMethod = NULL, getMainAttributesMethod = NULL, closeJarMethod = NULL, getValueMethod = NULL;
	jobject jarFileObject, manifest, attributes;
	jstring mainClassString = NULL;
	jstring jarFileString, headerString;
	const _TCHAR *mainClass;
	
	/* get the classes we need */
	jarFileClass = (*env)->FindClass(env, "java/util/jar/JarFile");
	if (jarFileClass != NULL) {
		manifestClass = (*env)->FindClass(env, "java/util/jar/Manifest");
		if (manifestClass != NULL) {
			attributesClass = (*env)->FindClass(env, "java/util/jar/Attributes");
		}
	}
	if ((*env)->ExceptionOccurred(env)) {
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
	if (attributesClass == NULL)
		return NULL;
	
	/* find the methods */
	jarFileConstructor = (*env)->GetMethodID(env, jarFileClass, "<init>", "(Ljava/lang/String;Z)V");
	if(jarFileConstructor != NULL) {
		getManifestMethod = (*env)->GetMethodID(env, jarFileClass, "getManifest", "()Ljava/util/jar/Manifest;");
		if(getManifestMethod != NULL) {
			closeJarMethod = (*env)->GetMethodID(env, jarFileClass, "close", "()V");
			if (closeJarMethod != NULL) {
				getMainAttributesMethod = (*env)->GetMethodID(env, manifestClass, "getMainAttributes", "()Ljava/util/jar/Attributes;");
				if (getMainAttributesMethod != NULL) {
					getValueMethod = (*env)->GetMethodID(env, attributesClass, "getValue", "(Ljava/lang/String;)Ljava/lang/String;");
				}
			}
		}
	}
	if ((*env)->ExceptionOccurred(env)) {
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
	if (getValueMethod == NULL)
		return NULL;
	
	/* jarFileString = new String(jarFile); */
	jarFileString = newJavaString(env, jarFile);
	 /* headerString = new String("Main-Class"); */
	 headerString = newJavaString(env, _T_ECLIPSE("Main-Class"));
	if (jarFileString != NULL && headerString != NULL) {
		/* jarfileObject = new JarFile(jarFileString, false); */
		jarFileObject = (*env)->NewObject(env, jarFileClass, jarFileConstructor, jarFileString, JNI_FALSE);
		if (jarFileObject != NULL) { 
			/* manifest = jarFileObject.getManifest(); */
			 manifest = (*env)->CallObjectMethod(env, jarFileObject, getManifestMethod);
			 if (manifest != NULL) {
				 /*jarFileObject.close() */
				 (*env)->CallVoidMethod(env, jarFileObject, closeJarMethod);
				 if (!(*env)->ExceptionOccurred(env)) {
					 /* attributes = manifest.getMainAttributes(); */
					 attributes = (*env)->CallObjectMethod(env, manifest, getMainAttributesMethod);
					 if (attributes != NULL) {
						 /* mainClassString = attributes.getValue(headerString); */
						 mainClassString = (*env)->CallObjectMethod(env, attributes, getValueMethod, headerString);
					 }
				 }
			 }
			 (*env)->DeleteLocalRef(env, jarFileObject);
		}
	}
	
	if (jarFileString != NULL)
		(*env)->DeleteLocalRef(env, jarFileString);
	if (headerString != NULL)
		(*env)->DeleteLocalRef(env, headerString);
	
	if ((*env)->ExceptionOccurred(env)) {
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
	
	if (mainClassString == NULL)
		return NULL;
	
	mainClass = JNI_GetStringChars(env, mainClassString);
	if(mainClass != NULL) {
		int i = -1;
		char *result = toNarrow(mainClass);
		JNI_ReleaseStringChars(env, mainClassString, mainClass);
		
		/* replace all the '.' with '/' */
		while(result[++i] != '\0') {
			if(result[i] == '.')
				result[i] = '/';
		}
		return result;
	}
	return NULL;
}

void cleanupVM(int exitCode) {
	JNIEnv * localEnv = env;
	if (jvm == 0)
		return;
	
	if (secondThread)
		(*jvm)->AttachCurrentThread(jvm, (void**)&localEnv, NULL);
	else
		localEnv = env;
	if (localEnv == 0)
		return;
	
	/* we call System.exit() unless osgi.noShutdown is set */
	if (shouldShutdown(env)) {
		jclass systemClass = NULL;
		jmethodID exitMethod = NULL;
		systemClass = (*env)->FindClass(env, "java/lang/System");
		if (systemClass != NULL) {
			exitMethod = (*env)->GetStaticMethodID(env, systemClass, "exit", "(I)V");
			if (exitMethod != NULL) {
				(*env)->CallStaticVoidMethod(env, systemClass, exitMethod, exitCode);
			}
		}
		if ((*env)->ExceptionOccurred(env)) {
			(*env)->ExceptionDescribe(env);
			(*env)->ExceptionClear(env);
		}
	}
	(*jvm)->DestroyJavaVM(jvm);
}

static int shouldShutdown(JNIEnv * env) {
	jclass booleanClass = NULL;
	jmethodID method = NULL;
	jstring arg = NULL;
	jboolean result = 0;
	
	booleanClass = (*env)->FindClass(env, "java/lang/Boolean");
	if (booleanClass != NULL) {
		method = (*env)->GetStaticMethodID(env, booleanClass, "getBoolean", "(Ljava/lang/String;)Z");
		if (method != NULL) {
			arg = newJavaString(env, _T_ECLIPSE("osgi.noShutdown"));
			result = (*env)->CallStaticBooleanMethod(env, booleanClass, method, arg);
			(*env)->DeleteLocalRef(env, arg);
		}
	}
	if ((*env)->ExceptionOccurred(env)) {
		(*env)->ExceptionDescribe(env);
		(*env)->ExceptionClear(env);
	}
	return (result == 0);
}


