/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include <string.h>

#include "log.h"
#include "thread.h"
#include "system.h"
#include "system_java.h"

static JavaVM *javaVirtualMachine = NULL;

JNIEXPORT jint
JNI_OnLoad (JavaVM *vm, void *reserved) {
  javaVirtualMachine = vm;
  return JAVA_JNI_VERSION;
}

JNIEXPORT void
JNI_OnUnload (JavaVM *vm, void *reserved) {
  javaVirtualMachine = NULL;
}

JavaVM *
getJavaInvocationInterface (void) {
  return javaVirtualMachine;
}

typedef struct {
  JavaVM *virtualMachine;
  JNIEnv *nativeInterface;
  char *threadName;
} ThreadSpecificData;

static THREAD_SPECIFIC_DATA_NEW(tsdJavaNativeThread) {
  ThreadSpecificData *tsd;

  if ((tsd = malloc(sizeof(*tsd)))) {
    memset(tsd, 0, sizeof(*tsd));
    return tsd;
  } else {
    logMallocError();
  }

  return NULL;
}

static THREAD_SPECIFIC_DATA_DESTROY(tsdJavaNativeThread) {
  ThreadSpecificData *tsd = data;

  {
    JavaVM *vm = tsd->virtualMachine;
    (*vm)->DetachCurrentThread(vm);
  }

  logMessage(LOG_DEBUG, "thread detached from Java VM: %s", tsd->threadName);
  free(tsd->threadName);
  free(tsd);
}

THREAD_SPECIFIC_DATA_CONTROL(tsdJavaNativeThread);

static char *
getJavaThreadName (JNIEnv *env) {
  char *name = NULL;
  static jclass Thread_class = NULL;

  if (findJavaClass(env, &Thread_class, JAVA_OBJ_THREAD)) {
    static jmethodID Thread_currentThread = 0;

    if (findJavaStaticMethod(env, &Thread_currentThread, Thread_class, "currentThread",
                             JAVA_SIG_METHOD(JAVA_SIG_THREAD, 
                                            ))) {
      jobject thread = (*env)->CallStaticObjectMethod(env, Thread_class, Thread_currentThread);

      if (!clearJavaException(env, 1)) {
        static jmethodID Thread_getName = 0;

        if (findJavaInstanceMethod(env, &Thread_getName, Thread_class, "getName",
                                   JAVA_SIG_METHOD(JAVA_SIG_STRING, 
                                                  ))) {
          jstring jName = (*env)->CallObjectMethod(env, thread, Thread_getName);

          if (!clearJavaException(env, 1)) {
            jboolean isCopy;
            const char *cName = (*env)->GetStringUTFChars(env, jName, &isCopy);

            if (!(name = strdup(cName))) {
              logMallocError();
            }

            (*env)->ReleaseStringUTFChars(env, jName, cName);
            (*env)->DeleteLocalRef(env, jName);
          }
        }

        (*env)->DeleteLocalRef(env, thread);
      }
    }
  }

  return name;
}

JNIEnv *
getJavaNativeInterface (void) {
  JavaVM *vm = getJavaInvocationInterface();

#ifdef __ANDROID__
  JNIEnv *env = NULL;
#else /* __ANDROID__ */
  void *env = NULL;
#endif /* __ANDROID__ */

  if (vm) {
    jint result = (*vm)->GetEnv(vm, (void **)&env, JAVA_JNI_VERSION);

    if (result != JNI_OK) {
      if (result == JNI_EDETACHED) {
        JavaVMAttachArgs args = {
          .version = JAVA_JNI_VERSION,
          .name = NULL,
          .group = NULL
        };

        if ((result = (*vm)->AttachCurrentThread(vm, &env, &args)) < 0) {
          logMessage(LOG_WARNING, "Java AttachCurrentThread error: %d", result);
        } else {
          ThreadSpecificData *tsd = getThreadSpecificData(&tsdJavaNativeThread);
          tsd->virtualMachine = vm;
          tsd->nativeInterface = env;
          tsd->threadName = getJavaThreadName(env);

          logMessage(LOG_DEBUG, "thread attached to Java VM: %s", tsd->threadName);
        }
      } else {
        logMessage(LOG_WARNING, "Java GetEnv error: %d", result);
      }
    }
  }

  return env;
}

int
clearJavaException (JNIEnv *env, int describe) {
  int exceptionOccurred = (*env)->ExceptionCheck(env);

  if (exceptionOccurred) {
    if (describe) (*env)->ExceptionDescribe(env);
    (*env)->ExceptionClear(env);
  }

  return exceptionOccurred;
}

static jobject javaClassLoaderInstance = NULL;
static jclass javaClassLoaderClass = NULL;
static jmethodID loadClassMethod = 0;

int
setJavaClassLoader (JNIEnv *env, jobject instance) {
  if (instance) {
    javaClassLoaderInstance = (*env)->NewGlobalRef(env, instance);

    if (javaClassLoaderInstance) {
      jclass class = (*env)->GetObjectClass(env, instance);

      if (class) {
        javaClassLoaderClass = (*env)->NewGlobalRef(env, class);

        (*env)->DeleteLocalRef(env, class);
        class = NULL;

        if (javaClassLoaderClass) {
          jmethodID method = (*env)->GetMethodID(env, javaClassLoaderClass, "loadClass",
                                                 JAVA_SIG_METHOD(JAVA_SIG_CLASS,
                                                                 JAVA_SIG_STRING // className
                                                                ));

          if (method) {
            loadClassMethod = method;
            return 1;
          }

          (*env)->DeleteGlobalRef(env, javaClassLoaderClass);
        }
      }

      (*env)->DeleteGlobalRef(env, javaClassLoaderInstance);
    }
  }

  javaClassLoaderInstance = NULL;
  javaClassLoaderClass = NULL;
  loadClassMethod = 0;
  return 0;
}

static jclass
loadJavaClass (JNIEnv *env, const char *path) {
  size_t size = strlen(path) + 1;
  char cName[size];

  jclass class = NULL;
  jobject jName;

  {
    const char *p = path;
    char *n = cName;
    char c;

    do {
      c = *p++;
      if (c == '/') c = '.';
      *n++ = c;
    } while (c);
  }

  if ((jName = (*env)->NewStringUTF(env, cName))) {
    jclass result = (*env)->CallObjectMethod(env, javaClassLoaderInstance, loadClassMethod, jName);

    if (clearJavaException(env, 1)) {
      (*env)->DeleteLocalRef(env, result);
    } else {
      class = result;
    }

    (*env)->DeleteLocalRef(env, jName);
  } else {
    logMallocError();
  }

  return class;
}

int
findJavaClass (JNIEnv *env, jclass *class, const char *path) {
  if (*class) return 1;

  {
    jclass localReference = loadClassMethod?
                              loadJavaClass(env, path):
                              (*env)->FindClass(env, path);

    if (localReference) {
      jclass globalReference = (*env)->NewGlobalRef(env, localReference);

      (*env)->DeleteLocalRef(env, localReference);
      localReference = NULL;

      if (globalReference) {
        logMessage(LOG_DEBUG, "java class found: %s", path);
        *class = globalReference;
        return 1;
      } else {
        logMallocError();
        clearJavaException(env, 0);
      }
    } else {
      logMessage(LOG_ERR, "java class not found: %s", path);
      clearJavaException(env, 1);
    }
  }

  return 0;
}

int
findJavaInstanceMethod (
  JNIEnv *env, jmethodID *method,
  jclass class, const char *name, const char *signature
) {
  if (!*method) {
    if (!(*method = (*env)->GetMethodID(env, class, name, signature))) {
      logMessage(LOG_ERR, "java instance method not found: %s: %s", name, signature);
      clearJavaException(env, 0);
      return 0;
    }

    logMessage(LOG_DEBUG, "java instance method found: %s: %s", name, signature);
  }

  return 1;
}

int
findJavaStaticMethod (
  JNIEnv *env, jmethodID *method,
  jclass class, const char *name, const char *signature
) {
  if (!*method) {
    if (!(*method = (*env)->GetStaticMethodID(env, class, name, signature))) {
      logMessage(LOG_ERR, "java static method not found: %s: %s", name, signature);
      clearJavaException(env, 0);
      return 0;
    }

    logMessage(LOG_DEBUG, "java static method found: %s: %s", name, signature);
  }

  return 1;
}

int
findJavaConstructor (
  JNIEnv *env, jmethodID *constructor,
  jclass class, const char *signature
) {
  return findJavaInstanceMethod(env, constructor, class, JAVA_CONSTRUCTOR_NAME, signature);
}

int
findJavaInstanceField (
  JNIEnv *env, jfieldID *field,
  jclass class, const char *name, const char *signature
) {
  if (!*field) {
    if (!(*field = (*env)->GetFieldID(env, class, name, signature))) {
      logMessage(LOG_ERR, "java instance field not found: %s: %s", name, signature);
      clearJavaException(env, 0);
      return 0;
    }

    logMessage(LOG_DEBUG, "java instance field found: %s: %s", name, signature);
  }

  return 1;
}

int
findJavaStaticField (
  JNIEnv *env, jfieldID *field,
  jclass class, const char *name, const char *signature
) {
  if (!*field) {
    if (!(*field = (*env)->GetStaticFieldID(env, class, name, signature))) {
      logMessage(LOG_ERR, "java static field not found: %s: %s", name, signature);
      clearJavaException(env, 0);
      return 0;
    }

    logMessage(LOG_DEBUG, "java static field found: %s: %s", name, signature);
  }

  return 1;
}

char *
getJavaLocaleName (void) {
  char *name = NULL;
  JNIEnv *env;

  if ((env = getJavaNativeInterface())) {
    jclass Locale_class = NULL;

    if (findJavaClass(env, &Locale_class, JAVA_OBJ_LOCALE)) {
      jmethodID Locale_getDefault = 0;

      if (findJavaStaticMethod(env, &Locale_getDefault, Locale_class, "getDefault",
                               JAVA_SIG_METHOD(JAVA_SIG_LOCALE, 
                                              ))) {
        jobject locale = (*env)->CallStaticObjectMethod(env, Locale_class, Locale_getDefault);

        if (!clearJavaException(env, 1)) {
          jmethodID Locale_toString = 0;

          if (findJavaInstanceMethod(env, &Locale_toString, Locale_class, "toString",
                                     JAVA_SIG_METHOD(JAVA_SIG_STRING, 
                                                    ))) {
            jstring jName = (*env)->CallObjectMethod(env, locale, Locale_toString);

            if (!clearJavaException(env, 1)) {
              jboolean isCopy;
              const char *cName = (*env)->GetStringUTFChars(env, jName, &isCopy);

              if (!(name = strdup(cName))) {
                logMallocError();
              }

              (*env)->ReleaseStringUTFChars(env, jName, cName);
              (*env)->DeleteLocalRef(env, jName);
            }
          }

          (*env)->DeleteLocalRef(env, locale);
        }
      }
    }
  }

  return name;
}

#if defined(__ANDROID__)
#include <locale.h>
#include "messages.h"

static void
initializeAndroidEnvironment (JNIEnv *env) {
  {
    static jclass class = NULL;

    if (findJavaClass(env, &class, JAVA_OBJ_BRLTTY("BrailleApplication"))) {
      static jmethodID method = 0;

      if (findJavaStaticMethod(env, &method, class, "getCurrentLocale",
                               JAVA_SIG_METHOD(JAVA_SIG_STRING, 
                                              ))) {
        jstring jLocale = (*env)->CallStaticObjectMethod(env, class, method);

        if (!clearJavaException(env, 1)) {
          if (jLocale) {
            jboolean isCopy;
            const char *cLocale = (*env)->GetStringUTFChars(env, jLocale, &isCopy);

            if (cLocale) {
              if (setMessagesLocale(cLocale)) {
              }

              (*env)->ReleaseStringUTFChars(env, jLocale, cLocale);
            }

            (*env)->DeleteLocalRef(env, jLocale);
          }
        }
      }
    }
  }
}
#endif /* platform-speciofic initialization */

void
initializeSystemObject (void) {
#if defined(__ANDROID__)
  initializeAndroidEnvironment(getJavaNativeInterface());
#endif /* platform-speciofic initialization */
}
