/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "jsvc.h"

#ifdef OS_CYGWIN
typedef long long __int64;
#endif
#include <unistd.h>
#include <jni.h>

#ifdef CHARSET_EBCDIC
#ifdef OSD_POSIX
#include <ascii_ebcdic.h>
#define jsvc_xlate_to_ascii(b) _e2a(b)
#define jsvc_xlate_from_ascii(b) _a2e(b)
#endif
#else
#define jsvc_xlate_to_ascii(b)         /* NOOP */
#define jsvc_xlate_from_ascii(b)       /* NOOP */
#endif

static JavaVM *jvm = NULL;
static JNIEnv *env = NULL;
static jclass cls = NULL;

#define FALSE 0
#define TRUE !FALSE

static void shutdown(JNIEnv * env, jobject source, jboolean reload)
{
    log_debug("Shutdown requested (reload is %d)", reload);
    if (reload == TRUE)
        main_reload();
    else
        main_shutdown();
}

static void failed(JNIEnv * env, jobject source, jstring message)
{
    if (message) {
        const char *msg = (*env)->GetStringUTFChars(env, message, NULL);
        log_error("Failed %s", msg ? msg : "(null)");
        if (msg)
            (*env)->ReleaseStringUTFChars(env, message, msg);
    }
    else
        log_error("Failed requested");
    main_shutdown();
}

/* Automatically restart when the JVM crashes */
static void java_abort123(void)
{
    exit(123);
}

char *java_library(arg_data *args, home_data *data)
{
    char *libf = NULL;

    /* Did we find ANY virtual machine? */
    if (data->jnum == 0) {
        log_error("Cannot find any VM in Java Home %s", data->path);
        return NULL;
    }

    /* Select the VM */
    if (args->name == NULL) {
        libf = data->jvms[0]->libr;
        log_debug("Using default JVM in %s", libf);
    }
    else {
        int x;
        for (x = 0; x < data->jnum; x++) {
            if (data->jvms[x]->name == NULL)
                continue;
            if (strcmp(args->name, data->jvms[x]->name) == 0) {
                libf = data->jvms[x]->libr;
                log_debug("Using specific JVM in %s", libf);
                break;
            }
        }
        if (libf == NULL) {
            log_error("Invalid JVM name specified %s", args->name);
            return NULL;
        }
    }
    return libf;
}

typedef jint(*jvm_create_t) (JavaVM **, JNIEnv **, JavaVMInitArgs *);

bool java_signal(void)
{
    jmethodID method;
    jboolean ret;
    char start[] = "signal";
    char startparams[] = "()Z";

    jsvc_xlate_to_ascii(start);
    jsvc_xlate_to_ascii(startparams);
    method = (*env)->GetStaticMethodID(env, cls, start, startparams);
    if (method == NULL) {
        (*env)->ExceptionClear(env);
        log_error("Cannot find DaemonLoader \"signal\" method");
        return false;
    }

    ret = (*env)->CallStaticBooleanMethod(env, cls, method);
    /* Clear any pending exception
     * so we can continue calling native methods
     */
    (*env)->ExceptionClear(env);
    log_debug("Daemon signal method returned %s", ret ? "true" : "false");
    return ret;
}

/* Initialize the JVM and its environment, loading libraries and all */
bool java_init(arg_data *args, home_data *data)
{
#ifdef OS_DARWIN
    dso_handle apph = NULL;
    char appf[1024];
    struct stat sb;
#endif /* ifdef OS_DARWIN */
    jvm_create_t symb = NULL;
    JNINativeMethod nativemethods[2];
    JavaVMOption *opt = NULL;
    dso_handle libh = NULL;
    JavaVMInitArgs arg;
    char *libf = NULL;
    jint ret;
    int x;
    char loaderclass[] = LOADER;
    char shutdownmethod[] = "shutdown";
    char shutdownparams[] = "(Z)V";
    char failedmethod[] = "failed";
    char failedparams[] = "(Ljava/lang/String;)V";
    char daemonprocid[64];
    /* Decide WHAT virtual machine we need to use */
    libf = java_library(args, data);
    if (libf == NULL) {
        log_error("Cannot locate JVM library file");
        return false;
    }

    /* Some Java options require environment variables to be set before loading
     * Java when using JNI
     */
    for (x = 0; x < args->onum; x++) {
        if (!strncmp(args->opts[x], "-XX:NativeMemoryTracking=", 25)) {
            fprintf(stdout, "Found [%s]\n", args->opts[x]);
            char *value = args->opts[x] + 25;
            fprintf(stdout, "Found value [%s]\n", value);
            if (strcmp(value, "off")) {
                snprintf(daemonprocid, sizeof(daemonprocid), "NMT_LEVEL_%d=%s", (int)getpid(), value);
                fprintf(stdout, "Setting environment entry [%s]\n", daemonprocid);
                putenv(daemonprocid);
            }
        }
    }

    /* Initialize the DSO library */
    if (dso_init() != true) {
        log_error("Cannot initialize the dynamic library loader");
        return false;
    }

    /* Load the JVM library */
#if !defined(OSD_POSIX)
    libh = dso_link(libf);
    if (libh == NULL) {
        log_error("Cannot dynamically link to %s", libf);
        log_error("%s", dso_error());
        return false;
    }
    log_debug("JVM library %s loaded", libf);
#endif

#ifdef OS_DARWIN
    /*
       MacOS/X actually has two libraries, one with the REAL vm, and one for
       the VM startup.
       - JVM 1.6, the library name is libverify.dylib
       - JVM 1.7 onwards, the library name is libjli.dylib
     */
    if (replace(appf, 1024, "$JAVA_HOME/../Libraries/libverify.dylib",
                "$JAVA_HOME", data->path) != 0) {
        log_error("Cannot replace values in loader library");
        return false;
    }
    if (stat(appf, &sb)) {
        if (replace(appf, 1024, "$JAVA_HOME/../MacOS/libjli.dylib", "$JAVA_HOME", data->path) != 0) {
            log_error("Cannot replace values in loader library");
            return false;
        }
    }
    // DAEMON-331 Alternative path for custom OpenJDK builds
    if (stat(appf, &sb)) {
        if (replace(appf, 1024, "$JAVA_HOME/lib/jli/libjli.dylib", "$JAVA_HOME", data->path) != 0) {
            log_error("Cannot replace values in loader library");
            return false;
        }
    }
    apph = dso_link(appf);
    if (apph == NULL) {
        log_error("Cannot load required shell library %s", appf);
        return false;
    }
    log_debug("Shell library %s loaded", appf);
#endif /* ifdef OS_DARWIN */
#if defined(OSD_POSIX)
    /* BS2000 does not allow to call JNI_CreateJavaVM indirectly */
#else
    symb = (jvm_create_t) dso_symbol(libh, "JNI_CreateJavaVM");
    if (symb == NULL) {
#ifdef OS_DARWIN
        symb = (jvm_create_t) dso_symbol(apph, "JNI_CreateJavaVM");
        if (symb == NULL) {
#endif /* ifdef OS_DARWIN */
            log_error("Cannot find JVM library entry point");
            return false;
#ifdef OS_DARWIN
        }
#endif /* ifdef OS_DARWIN */
    }
    log_debug("JVM library entry point found (0x%08X)", symb);
#endif

    /* Prepare the VM initialization arguments */

    /* Minimum Java version is Java 6 */
    arg.version = JNI_VERSION_1_6;

#if defined(OSD_POSIX)
    if (JNI_GetDefaultJavaVMInitArgs(&arg) < 0) {
        log_error("Cannot init default JVM default args");
        return false;
    }
#endif
    arg.ignoreUnrecognized = FALSE;
    arg.nOptions = args->onum + 5;     /* pid, ppid, version, class and abort */
    opt = (JavaVMOption *) malloc(arg.nOptions * sizeof(JavaVMOption));
    for (x = 0; x < args->onum; x++) {
        opt[x].optionString = strdup(args->opts[x]);
        jsvc_xlate_to_ascii(opt[x].optionString);
        opt[x].extraInfo = NULL;
    }
    /* Add our daemon process id */
    snprintf(daemonprocid, sizeof(daemonprocid), "-Dcommons.daemon.process.id=%d", (int)getpid());
    opt[x].optionString = strdup(daemonprocid);
    jsvc_xlate_to_ascii(opt[x].optionString);
    opt[x++].extraInfo = NULL;

    snprintf(daemonprocid, sizeof(daemonprocid),
             "-Dcommons.daemon.process.parent=%d", (int)getppid());
    opt[x].optionString = strdup(daemonprocid);
    jsvc_xlate_to_ascii(opt[x].optionString);
    opt[x++].extraInfo = NULL;

    snprintf(daemonprocid, sizeof(daemonprocid),
             "-Dcommons.daemon.version=%s", JSVC_VERSION_STRING);
    opt[x].optionString = strdup(daemonprocid);
    jsvc_xlate_to_ascii(opt[x].optionString);
    opt[x++].extraInfo = NULL;

    /* DBCP-388. For the benefit of jconsole. */
    snprintf(daemonprocid, sizeof(daemonprocid), "-Dsun.java.command=%s", args->clas);
    opt[x].optionString = strdup(daemonprocid);
    jsvc_xlate_to_ascii(opt[x].optionString);
    opt[x++].extraInfo = NULL;

    opt[x].optionString = strdup("abort");
    jsvc_xlate_to_ascii(opt[x].optionString);
    opt[x].extraInfo = (void *)java_abort123;

    arg.options = opt;

    /* Do some debugging */
    if (log_debug_flag == true) {
        log_debug("+-- DUMPING JAVA VM CREATION ARGUMENTS -----------------");
        log_debug("| Version:                       %#08x", arg.version);
        log_debug("| Ignore Unrecognized Arguments: %s",
                  arg.ignoreUnrecognized == TRUE ? "True" : "False");
        log_debug("| Extra options:                 %d", args->onum);

        for (x = 0; x < args->onum; x++) {
            jsvc_xlate_from_ascii(opt[x].optionString);
            log_debug("|   \"%s\" (0x%08x)", opt[x].optionString, opt[x].extraInfo);
            jsvc_xlate_to_ascii(opt[x].optionString);
        }
        log_debug("+-------------------------------------------------------");
        log_debug("| Internal options:              %d", arg.nOptions - args->onum);

        for (; x < arg.nOptions; x++) {
            jsvc_xlate_from_ascii(opt[x].optionString);
            log_debug("|   \"%s\" (0x%08x)", opt[x].optionString, opt[x].extraInfo);
            jsvc_xlate_to_ascii(opt[x].optionString);
        }
        log_debug("+-------------------------------------------------------");
    }

    /* And finally create the Java VM */
#if defined(OSD_POSIX)
    ret = JNI_CreateJavaVM(&jvm, &env, &arg);
#else
    ret = (*symb) (&jvm, &env, &arg);
#endif
    if (ret < 0) {
        log_error("Cannot create Java VM");
        return false;
    }
    log_debug("Java VM created successfully");

    jsvc_xlate_to_ascii(loaderclass);
    cls = (*env)->FindClass(env, loaderclass);
    jsvc_xlate_from_ascii(loaderclass);
    if (cls == NULL) {
        log_error("Cannot find daemon loader %s", loaderclass);
        return false;
    }
    log_debug("Class %s found", loaderclass);

    jsvc_xlate_to_ascii(shutdownmethod);
    nativemethods[0].name = shutdownmethod;
    jsvc_xlate_to_ascii(shutdownparams);
    nativemethods[0].signature = shutdownparams;
    nativemethods[0].fnPtr = (void *)shutdown;
    jsvc_xlate_to_ascii(failedmethod);
    nativemethods[1].name = failedmethod;
    jsvc_xlate_to_ascii(failedparams);
    nativemethods[1].signature = failedparams;
    nativemethods[1].fnPtr = (void *)failed;

    if ((*env)->RegisterNatives(env, cls, nativemethods, 2) != 0) {
        log_error("Cannot register native methods");
        return false;
    }
    log_debug("Native methods registered");

    return true;
}

/* Destroy the Java VM */
bool JVM_destroy(int exit)
{
    jclass system = NULL;
    jmethodID method;
    char System[] = "java/lang/System";
    char exitclass[] = "exit";
    char exitparams[] = "(I)V";

    jsvc_xlate_to_ascii(System);
    system = (*env)->FindClass(env, System);
    jsvc_xlate_from_ascii(System);
    if (system == NULL) {
        log_error("Cannot find class %s", System);
        return false;
    }

    jsvc_xlate_to_ascii(exitclass);
    jsvc_xlate_to_ascii(exitparams);
    method = (*env)->GetStaticMethodID(env, system, exitclass, exitparams);
    if (method == NULL) {
        log_error("Cannot find \"System.exit(int)\" entry point");
        return false;
    }

    log_debug("Calling System.exit(%d)", exit);
    (*env)->CallStaticVoidMethod(env, system, method, (jint) exit);

    /* We shouldn't get here, but just in case... */
    log_debug("Destroying the Java VM");
    if ((*jvm)->DestroyJavaVM(jvm) != 0)
        return false;
    log_debug("Java VM destroyed");
    return true;
}

/* Call the load method in our DaemonLoader class */
bool java_load(arg_data *args)
{
    jclass stringClass = NULL;
    jstring className = NULL;
    jstring currentArgument = NULL;
    jobjectArray stringArray = NULL;
    jmethodID method = NULL;
    jboolean ret = FALSE;
    int x;
    char lang[] = "java/lang/String";
    char load[] = "load";
    char loadparams[] = "(Ljava/lang/String;[Ljava/lang/String;)Z";

    jsvc_xlate_to_ascii(args->clas);
    className = (*env)->NewStringUTF(env, args->clas);
    jsvc_xlate_from_ascii(args->clas);
    if (className == NULL) {
        log_error("Cannot create string for class name");
        return false;
    }

    jsvc_xlate_to_ascii(lang);
    stringClass = (*env)->FindClass(env, lang);
    if (stringClass == NULL) {
        log_error("Cannot find class java/lang/String");
        return false;
    }

    stringArray = (*env)->NewObjectArray(env, args->anum, stringClass, NULL);
    if (stringArray == NULL) {
        log_error("Cannot create arguments array");
        return false;
    }

    for (x = 0; x < args->anum; x++) {
        jsvc_xlate_to_ascii(args->args[x]);
        currentArgument = (*env)->NewStringUTF(env, args->args[x]);
        if (currentArgument == NULL) {
            jsvc_xlate_from_ascii(args->args[x]);
            log_error("Cannot create string for argument %s", args->args[x]);
            return false;
        }
        (*env)->SetObjectArrayElement(env, stringArray, x, currentArgument);
    }

    jsvc_xlate_to_ascii(load);
    jsvc_xlate_to_ascii(loadparams);
    method = (*env)->GetStaticMethodID(env, cls, load, loadparams);
    if (method == NULL) {
        log_error("Cannot find Daemon Loader \"load\" entry point");
        return false;
    }

    log_debug("Daemon loading...");
    ret = (*env)->CallStaticBooleanMethod(env, cls, method, className, stringArray);
    if (ret == FALSE) {
        log_error("Cannot load daemon");
        return false;
    }

    log_debug("Daemon loaded successfully");
    return true;
}

/* Call the start method in our daemon loader */
bool java_start(void)
{
    jmethodID method;
    jboolean ret;
    char start[] = "start";
    char startparams[] = "()Z";

    jsvc_xlate_to_ascii(start);
    jsvc_xlate_to_ascii(startparams);
    method = (*env)->GetStaticMethodID(env, cls, start, startparams);
    if (method == NULL) {
        log_error("Cannot find Daemon Loader \"start\" entry point");
        return false;
    }

    ret = (*env)->CallStaticBooleanMethod(env, cls, method);
    if (ret == FALSE) {
        log_error("Cannot start daemon");
        return false;
    }

    log_debug("Daemon started successfully");
    return true;
}

/*
 * call the java sleep to prevent problems with threads
 */
void java_sleep(int wait)
{
    jclass clsThread;
    jmethodID method;
    char jsleep[] = "sleep";
    char jsleepparams[] = "(J)V";
    char jthread[] = "java/lang/Thread";

    jsvc_xlate_to_ascii(jsleep);
    jsvc_xlate_to_ascii(jsleepparams);
    jsvc_xlate_to_ascii(jthread);

    clsThread = (*env)->FindClass(env, jthread);
    if (clsThread == NULL) {
        log_error("Cannot find java/lang/Thread class");
        return;
    }
    method = (*env)->GetStaticMethodID(env, clsThread, jsleep, jsleepparams);
    if (method == NULL) {
        log_error("Cannot found the sleep entry point");
        return;
    }

    (*env)->CallStaticVoidMethod(env, clsThread, method, (jlong) wait * 1000);
}

/* Call the stop method in our daemon loader */
bool java_stop(void)
{
    jmethodID method;
    jboolean ret;
    char stop[] = "stop";
    char stopparams[] = "()Z";

    jsvc_xlate_to_ascii(stop);
    jsvc_xlate_to_ascii(stopparams);
    method = (*env)->GetStaticMethodID(env, cls, stop, stopparams);
    if (method == NULL) {
        log_error("Cannot found Daemon Loader \"stop\" entry point");
        return false;
    }

    ret = (*env)->CallStaticBooleanMethod(env, cls, method);
    if (ret == FALSE) {
        log_error("Cannot stop daemon");
        return false;
    }

    log_debug("Daemon stopped successfully");
    return true;
}

/* Call the version method in our daemon loader */
bool java_version(void)
{
    jmethodID method;
    char version[] = "version";
    char versionparams[] = "()V";

    jsvc_xlate_to_ascii(version);
    jsvc_xlate_to_ascii(versionparams);
    method = (*env)->GetStaticMethodID(env, cls, version, versionparams);
    if (method == NULL) {
        log_error("Cannot found Daemon Loader \"version\" entry point");
        return false;
    }

    (*env)->CallStaticVoidMethod(env, cls, method);
    return true;
}

/* Call the check method in our DaemonLoader class */
bool java_check(arg_data *args)
{
    jstring className = NULL;
    jmethodID method = NULL;
    jboolean ret = FALSE;
    char check[] = "check";
    char checkparams[] = "(Ljava/lang/String;)Z";

    log_debug("Checking daemon");

    jsvc_xlate_to_ascii(args->clas);
    className = (*env)->NewStringUTF(env, args->clas);
    jsvc_xlate_from_ascii(args->clas);
    if (className == NULL) {
        log_error("Cannot create string for class name");
        return false;
    }

    jsvc_xlate_to_ascii(check);
    jsvc_xlate_to_ascii(checkparams);
    method = (*env)->GetStaticMethodID(env, cls, check, checkparams);
    if (method == NULL) {
        log_error("Cannot found Daemon Loader \"check\" entry point");
        return false;
    }

    ret = (*env)->CallStaticBooleanMethod(env, cls, method, className);
    if (ret == FALSE) {
        log_error("An error was detected checking the %s daemon", args->clas);
        return false;
    }

    log_debug("Daemon checked successfully");
    return true;
}

/* Call the destroy method in our daemon loader */
bool java_destroy(void)
{
    jmethodID method;
    jboolean ret;
    char destroy[] = "destroy";
    char destroyparams[] = "()Z";

    jsvc_xlate_to_ascii(destroy);
    jsvc_xlate_to_ascii(destroyparams);
    method = (*env)->GetStaticMethodID(env, cls, destroy, destroyparams);
    if (method == NULL) {
        log_error("Cannot found Daemon Loader \"destroy\" entry point");
        return false;
    }

    ret = (*env)->CallStaticBooleanMethod(env, cls, method);
    if (ret == FALSE) {
        log_error("Cannot destroy daemon");
        return false;
    }

    log_debug("Daemon destroyed successfully");
    return true;
}
