/*******************************************************************************
 * Copyright (c) 2006, 2009 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at 
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * 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);
}


