/*
 * 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 <jni.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>

#include "embed.h"
#include "system_java.h"

#if defined(__ANDROID__)
#include <android/log.h>
#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_TARNAME, __VA_ARGS__)

#else /* LOG() */
#warning logging not supported
#define LOG(...)
#endif /* LOG() */

SYMBOL_POINTER(brlttyConstruct);
SYMBOL_POINTER(setJavaClassLoader);
SYMBOL_POINTER(brlttyDestruct);

SYMBOL_POINTER(brlttyEnableInterrupt);
SYMBOL_POINTER(brlttyDisableInterrupt);

SYMBOL_POINTER(brlttyInterrupt);
SYMBOL_POINTER(brlttyWait);

SYMBOL_POINTER(changeLogLevel);
SYMBOL_POINTER(changeLogCategories);

SYMBOL_POINTER(changeTextTable);
SYMBOL_POINTER(changeAttributesTable);
SYMBOL_POINTER(changeContractionTable);
SYMBOL_POINTER(changeKeyboardTable);

SYMBOL_POINTER(restartBrailleDriver);
SYMBOL_POINTER(changeBrailleDriver);
SYMBOL_POINTER(changeBrailleParameters);
SYMBOL_POINTER(changeBrailleDevice);

SYMBOL_POINTER(restartSpeechDriver);
SYMBOL_POINTER(changeSpeechDriver);
SYMBOL_POINTER(changeSpeechParameters);

SYMBOL_POINTER(restartScreenDriver);
SYMBOL_POINTER(changeScreenDriver);
SYMBOL_POINTER(changeScreenParameters);

SYMBOL_POINTER(changeMessageLocale);
SYMBOL_POINTER(showMessage);

typedef struct {
  const char *name;
  void *pointer;
} SymbolEntry;

#define BEGIN_SYMBOL_TABLE static const SymbolEntry symbolTable[] = {
#define END_SYMBOL_TABLE {.name=NULL} };
#define SYMBOL_ENTRY(symbol) {.name=#symbol, .pointer=&symbol##_p}

BEGIN_SYMBOL_TABLE
  SYMBOL_ENTRY(brlttyConstruct),
  SYMBOL_ENTRY(setJavaClassLoader),
  SYMBOL_ENTRY(brlttyDestruct),

  SYMBOL_ENTRY(brlttyEnableInterrupt),
  SYMBOL_ENTRY(brlttyDisableInterrupt),

  SYMBOL_ENTRY(brlttyInterrupt),
  SYMBOL_ENTRY(brlttyWait),

  SYMBOL_ENTRY(changeLogLevel),
  SYMBOL_ENTRY(changeLogCategories),

  SYMBOL_ENTRY(changeTextTable),
  SYMBOL_ENTRY(changeAttributesTable),
  SYMBOL_ENTRY(changeContractionTable),
  SYMBOL_ENTRY(changeKeyboardTable),

  SYMBOL_ENTRY(restartBrailleDriver),
  SYMBOL_ENTRY(changeBrailleDriver),
  SYMBOL_ENTRY(changeBrailleParameters),
  SYMBOL_ENTRY(changeBrailleDevice),

  SYMBOL_ENTRY(restartSpeechDriver),
  SYMBOL_ENTRY(changeSpeechDriver),
  SYMBOL_ENTRY(changeSpeechParameters),

  SYMBOL_ENTRY(restartScreenDriver),
  SYMBOL_ENTRY(changeScreenDriver),
  SYMBOL_ENTRY(changeScreenParameters),

  SYMBOL_ENTRY(changeMessageLocale),
  SYMBOL_ENTRY(showMessage),
END_SYMBOL_TABLE

static void *coreHandle = NULL;

static jobject jArgumentArray = NULL;
static const char **cArgumentArray = NULL;
static int cArgumentCount;

static void reportProblem (
  JNIEnv *env, const char *throwable,
  const char *format, ...
) PRINTF(3, 4);

static void
reportProblem (
  JNIEnv *env, const char *throwable,
  const char *format, ...
) {
  char message[0X100];

  {
    va_list arguments;

    va_start(arguments, format);
    vsnprintf(message, sizeof(message), format, arguments);
    va_end(arguments);
  }

  if (0) {
    FILE *stream = stderr;

    fprintf(stream, "%s\n", message);
    fflush(stream);
  }

  {
    jclass object = (*env)->FindClass(env, throwable);

    if (object) {
      (*env)->ThrowNew(env, object, message);
      (*env)->DeleteLocalRef(env, object);
    }
  }
}

static void
reportOutOfMemory (JNIEnv *env, const char *description) {
  reportProblem(env, JAVA_OBJ_OUT_OF_MEMORY_ERROR, "cannot allocate %s", description);
}

static int
prepareProgramArguments (JNIEnv *env, jstring arguments) {
  jsize count = (*env)->GetArrayLength(env, arguments);

  if ((jArgumentArray = (*env)->NewGlobalRef(env, arguments))) {
    if ((cArgumentArray = malloc((count + 2) * sizeof(*cArgumentArray)))) {
      cArgumentArray[0] = PACKAGE_TARNAME;
      cArgumentArray[count+1] = NULL;

      {
        unsigned int i;

        for (i=1; i<=count; i+=1) cArgumentArray[i] = NULL;

        for (i=1; i<=count; i+=1) {
          jstring jArgument = (*env)->GetObjectArrayElement(env, arguments, i-1);
          jboolean isCopy;
          const char *cArgument = (*env)->GetStringUTFChars(env, jArgument, &isCopy);

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

          if (!cArgument) {
            reportOutOfMemory(env, "C argument string");
            break;
          }

          cArgumentArray[i] = cArgument;
        }

        if (i > count) {
          cArgumentCount = count + 1;
          return 1;
        }
      }
    } else {
      reportOutOfMemory(env, "C argument array");
    }
  } else {
    reportOutOfMemory(env, "Java arguments array global reference");
  }

  return 0;
}

static int
loadCoreLibrary (JNIEnv *env) {
  if (coreHandle) return 1;

  if ((coreHandle = dlopen("libbrltty_core.so", RTLD_NOW | RTLD_GLOBAL))) {
    int allFound = 1;
    const SymbolEntry *symbol = symbolTable;

    while (symbol->name) {
      const void **pointer = symbol->pointer;

      if ((*pointer = dlsym(coreHandle, symbol->name))) {
        LOG("core symbol: %s -> %p", symbol->name, *pointer);
      } else {
        LOG("core symbol not found: %s", symbol->name);
        allFound = 0;
      }

      symbol += 1;
    }

    if (allFound) return 1;
  }

  reportProblem(env, JAVA_OBJ_UNSATISFIED_LINK_ERROR, "%s", dlerror());
  return 0;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, coreConstruct, jint,
  jobjectArray arguments, jobject classLoader
) {
  if (prepareProgramArguments(env, arguments)) {
    if (loadCoreLibrary(env)) {
      setJavaClassLoader_p(env, classLoader);
      return brlttyConstruct_p(cArgumentCount, (char **)cArgumentArray);
    }
  }

  return PROG_EXIT_FATAL;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, coreDestruct, jboolean
) {
  jboolean result = brlttyDestruct_p()? JNI_TRUE: JNI_FALSE;

/*
  {
    const SymbolEntry *symbol = symbolTable;

    while (symbol->name) {
      const void **pointer = symbol->pointer;
      *pointer = NULL;
      symbol += 1;
    }
  }

  if (coreHandle) {
    dlclose(coreHandle);
    coreHandle = NULL;
  }
*/

  if (jArgumentArray) {
    if (cArgumentArray) {
      unsigned int i = 0;

      while (cArgumentArray[++i]) {
        jstring jArgument = (*env)->GetObjectArrayElement(env, jArgumentArray, i-1);
        (*env)->ReleaseStringUTFChars(env, jArgument, cArgumentArray[i]);
        (*env)->DeleteLocalRef(env, jArgument);
        jArgument = NULL;
      }

      free(cArgumentArray);
      cArgumentArray = NULL;
    }

    (*env)->DeleteGlobalRef(env, jArgumentArray);
    jArgumentArray = NULL;
  }

  return result;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, coreEnableInterrupt, jboolean
) {
  return brlttyEnableInterrupt_p()? JNI_TRUE: JNI_FALSE;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, coreDisableInterrupt, jboolean
) {
  return brlttyDisableInterrupt_p()? JNI_TRUE: JNI_FALSE;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, coreInterrupt, jboolean,
  jboolean stop
) {
  return brlttyInterrupt_p((stop != JNI_FALSE)? WAIT_STOP: WAIT_CONTINUE)? JNI_TRUE: JNI_FALSE;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, coreWait, jboolean,
  jint duration
) {
  return (brlttyWait_p(duration) != WAIT_STOP)? JNI_TRUE: JNI_FALSE;
}

static jboolean
changeStringValue (JNIEnv *env, int (*change) (const char *cValue), jstring jValue) {
  jboolean result = JNI_FALSE;
  const char *cValue = (*env)->GetStringUTFChars(env, jValue, NULL);

  if (cValue) {
    if (change(cValue)) result = JNI_TRUE;
    (*env)->ReleaseStringUTFChars(env, jValue, cValue);
  } else {
    reportOutOfMemory(env, "C new value string");
  }

  return result;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeLogLevel, jboolean,
  jstring level
) {
  return changeStringValue(env, changeLogLevel_p, level);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeLogCategories, jboolean,
  jstring categories
) {
  return changeStringValue(env, changeLogCategories_p, categories);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeTextTable, jboolean,
  jstring name
) {
  return changeStringValue(env, changeTextTable_p, name);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeAttributesTable, jboolean,
  jstring name
) {
  return changeStringValue(env, changeAttributesTable_p, name);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeContractionTable, jboolean,
  jstring name
) {
  return changeStringValue(env, changeContractionTable_p, name);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeKeyboardTable, jboolean,
  jstring name
) {
  return changeStringValue(env, changeKeyboardTable_p, name);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, restartBrailleDriver, jboolean
) {
  restartBrailleDriver_p();
  return JNI_TRUE;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeBrailleDriver, jboolean,
  jstring driver
) {
  return changeStringValue(env, changeBrailleDriver_p, driver);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeBrailleParameters, jboolean,
  jstring parameters
) {
  return changeStringValue(env, changeBrailleParameters_p, parameters);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeBrailleDevice, jboolean,
  jstring device
) {
  return changeStringValue(env, changeBrailleDevice_p, device);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, restartSpeechDriver, jboolean
) {
  restartSpeechDriver_p();
  return JNI_TRUE;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeSpeechDriver, jboolean,
  jstring driver
) {
  return changeStringValue(env, changeSpeechDriver_p, driver);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeSpeechParameters, jboolean,
  jstring parameters
) {
  return changeStringValue(env, changeSpeechParameters_p, parameters);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, restartScreenDriver, jboolean
) {
  restartScreenDriver_p();
  return JNI_TRUE;
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeScreenDriver, jboolean,
  jstring driver
) {
  return changeStringValue(env, changeScreenDriver_p, driver);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeScreenParameters, jboolean,
  jstring parameters
) {
  return changeStringValue(env, changeScreenParameters_p, parameters);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, changeMessageLocale, jboolean,
  jstring locale
) {
  return changeStringValue(env, changeMessageLocale_p, locale);
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, showMessage, void,
  jstring jMessage
) {
  const char *cMessage = (*env)->GetStringUTFChars(env, jMessage, NULL);

  if (cMessage) {
    showMessage_p(cMessage);
    (*env)->ReleaseStringUTFChars(env, jMessage, cMessage);
  } else {
    reportOutOfMemory(env, "C new value string");
  }
}

JAVA_STATIC_METHOD (
  org_a11y_brltty_core_CoreWrapper, setEnvironmentVariable, jboolean,
  jstring jName, jstring jValue
) {
  jboolean isCopy;
  const char *cName = (*env)->GetStringUTFChars(env, jName, &isCopy);
  const char *cValue = (*env)->GetStringUTFChars(env, jValue, &isCopy);

  int cResult = setenv(cName, cValue, 1) != -1;
  jboolean jResult = cResult? JNI_TRUE: JNI_FALSE;

  if (cResult) {
    LOG("environment variable set: %s: %s", cName, cValue);
  } else {
    LOG("environment variable not set: %s: %s", cName, strerror(errno));
  }

  (*env)->ReleaseStringUTFChars(env, jName, cName);
  (*env)->ReleaseStringUTFChars(env, jValue, cValue);
  return jResult;
}

JNIEXPORT jint
JNI_OnLoad (JavaVM *vm, void *reserved) {
  JNIEnv *env;

  if ((*vm)->GetEnv(vm, (void **)&env, JAVA_JNI_VERSION) == JNI_OK) {
    loadCoreLibrary(env);
  }

  return JAVA_JNI_VERSION;
}
