/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed 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.
 */
#define _GNU_SOURCE /* for strcasestr(3) */
#include <vnet/vnet.h>

#define vl_api_version(n,v) static u32 vpe_api_version = (v);
#include <vpp-api/vpe.api.h>
#undef vl_api_version

#include <jni.h>
#include <jvpp-common/jvpp_common.h>
#include "org_openvpp_jvpp_VppJNIConnection.h"
#include "org_openvpp_jvpp_JVppRegistryImpl.h"

#include <vpp-api/vpe_msg_enum.h>
#define vl_typedefs             /* define message structures */
#include <vpp-api/vpe_all_api_h.h>
#undef vl_typedefs

#define vl_endianfun
#include <vpp-api/vpe_all_api_h.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...)
#define vl_printfun
#include <vpp-api/vpe_all_api_h.h>
#undef vl_printfun

/*
 * The Java runtime isn't compile w/ -fstack-protector,
 * so we have to supply missing external references for the
 * regular vpp libraries.
 */
void __stack_chk_guard(void) __attribute__((weak));
void __stack_chk_guard(void) {
}

typedef struct {
    /* UThread attachment */
    volatile u32 control_ping_result_ready;
    volatile i32 control_ping_retval;

    /* Control poing callback */
    jobject registryObject;
    jclass registryClass;
    jclass controlPingReplyClass;
    jclass callbackExceptionClass;

    /* Thread cleanup */
    pthread_key_t cleanup_rx_thread_key;

    /* Connected indication */
    volatile u8 is_connected;
} jvpp_registry_main_t;

jvpp_registry_main_t jvpp_registry_main __attribute__((aligned (64)));

void vl_client_add_api_signatures(vl_api_memclnt_create_t *mp) {
    /*
     * Send the main API signature in slot 0. This bit of code must
     * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
     */
    mp->api_versions[0] = clib_host_to_net_u32(vpe_api_version);
}

/* cleanup handler for RX thread */
static_always_inline void cleanup_rx_thread(void *arg) {
    jvpp_main_t * jm = &jvpp_main;
    jvpp_registry_main_t * rm = &jvpp_registry_main;

    vppjni_lock(jm, 99);

    int getEnvStat = (*jm->jvm)->GetEnv(jm->jvm, (void **) &(jm->jenv),
    JNI_VERSION_1_8);
    if (getEnvStat == JNI_EVERSION) {
        clib_warning("Unsupported JNI version\n");
        rm->control_ping_retval = VNET_API_ERROR_UNSUPPORTED_JNI_VERSION;
        goto out;
    } else if (getEnvStat != JNI_EDETACHED) {
        (*jm->jvm)->DetachCurrentThread(jm->jvm);
    }
    out: vppjni_unlock(jm);
}

static void vl_api_control_ping_reply_t_handler(
        vl_api_control_ping_reply_t * mp) {
    jvpp_main_t * jm = &jvpp_main;
    jvpp_registry_main_t * rm = &jvpp_registry_main;
    char was_thread_connected = 0;

    // attach to java thread if not attached
    int getEnvStat = (*jm->jvm)->GetEnv(jm->jvm, (void **) &(jm->jenv),
            JNI_VERSION_1_8);
    if (getEnvStat == JNI_EDETACHED) {
        if ((*jm->jvm)->AttachCurrentThread(jm->jvm, (void **) &(jm->jenv),
                NULL) != 0) {
            clib_warning("Failed to attach thread\n");
            rm->control_ping_retval =
                    VNET_API_ERROR_FAILED_TO_ATTACH_TO_JAVA_THREAD;
            goto out;
        }

        // workaround as we can't use pthread_cleanup_push
        pthread_key_create(&rm->cleanup_rx_thread_key, cleanup_rx_thread);
        // destructor is only called if the value of key is non null
        pthread_setspecific(rm->cleanup_rx_thread_key, (void *) 1);
        was_thread_connected = 1;
    } else if (getEnvStat == JNI_EVERSION) {
        clib_warning("Unsupported JNI version\n");
        rm->control_ping_retval = VNET_API_ERROR_UNSUPPORTED_JNI_VERSION;
        goto out;
    }

    if (was_thread_connected == 0) {
        JNIEnv *env = jm->jenv;
        if (mp->retval < 0) {
            call_on_error("controlPing", mp->context, mp->retval,
                    rm->registryClass, rm->registryObject,
                    rm->callbackExceptionClass);
        } else {
            jmethodID constructor = (*env)->GetMethodID(env,
                    rm->controlPingReplyClass, "<init>", "()V");
            jmethodID callbackMethod = (*env)->GetMethodID(env,
                    rm->registryClass, "onControlPingReply",
                    "(Lorg/openvpp/jvpp/dto/ControlPingReply;)V");

            jobject dto = (*env)->NewObject(env, rm->controlPingReplyClass,
                    constructor);

            jfieldID contextFieldId = (*env)->GetFieldID(env,
                    rm->controlPingReplyClass, "context", "I");
            (*env)->SetIntField(env, dto, contextFieldId,
                    clib_net_to_host_u32(mp->context));

            jfieldID clientIndexFieldId = (*env)->GetFieldID(env,
                    rm->controlPingReplyClass, "clientIndex", "I");
            (*env)->SetIntField(env, dto, clientIndexFieldId,
                    clib_net_to_host_u32(mp->client_index));

            jfieldID vpePidFieldId = (*env)->GetFieldID(env,
                    rm->controlPingReplyClass, "vpePid", "I");
            (*env)->SetIntField(env, dto, vpePidFieldId,
                    clib_net_to_host_u32(mp->vpe_pid));

            (*env)->CallVoidMethod(env, rm->registryObject, callbackMethod,
                    dto);
        }
    }

    out: rm->control_ping_result_ready = 1;
}

static int send_initial_control_ping() {
    f64 timeout;
    clib_time_t clib_time;
    vl_api_control_ping_t * mp;
    jvpp_main_t * jm = &jvpp_main;
    jvpp_registry_main_t * rm = &jvpp_registry_main;

    clib_time_init(&clib_time);

    rm->control_ping_result_ready = 0;
    mp = vl_msg_api_alloc(sizeof(*mp));
    memset(mp, 0, sizeof(*mp));
    mp->_vl_msg_id = ntohs(VL_API_CONTROL_PING);
    mp->client_index = jm->my_client_index;

    // send message:
    vl_msg_api_send_shmem(jm->vl_input_queue, (u8 *) &mp);

    // wait for results: Current time + 10 seconds is the timeout
    timeout = clib_time_now(&clib_time) + 10.0;
    int rv = VNET_API_ERROR_RESPONSE_NOT_READY;
    while (clib_time_now(&clib_time) < timeout) {
        if (rm->control_ping_result_ready == 1) {
            rv = rm->control_ping_retval;
            break;
        }
    }

    if (rv != 0) {
        clib_warning("common: first control ping failed: %d", rv);
    }

    return rv;
}

static int connect_to_vpe(char *name) {
    jvpp_main_t * jm = &jvpp_main;
    api_main_t * am = &api_main;

    if (vl_client_connect_to_vlib("/vpe-api", name, 32) < 0)
        return -1;

    jm->my_client_index = am->my_client_index;

    jm->vl_input_queue = am->shmem_hdr->vl_input_queue;

    vl_msg_api_set_handlers(VL_API_CONTROL_PING_REPLY, "control_ping_reply",
            vl_api_control_ping_reply_t_handler, vl_noop_handler,
            vl_api_control_ping_reply_t_endian,
            vl_api_control_ping_reply_t_print,
            sizeof(vl_api_control_ping_reply_t), 1);

    send_initial_control_ping();

    return 0;
}

JNIEXPORT jobject JNICALL Java_org_openvpp_jvpp_VppJNIConnection_clientConnect(
        JNIEnv *env, jclass obj, jstring clientName) {
    int rv;
    const char *client_name;
    void vl_msg_reply_handler_hookup(void);
    jvpp_main_t * jm = &jvpp_main;
    jvpp_registry_main_t * rm = &jvpp_registry_main;

    jclass connectionInfoClass = (*env)->FindClass(env,
            "org/openvpp/jvpp/VppJNIConnection$ConnectionInfo");
    jmethodID connectionInfoConstructor = (*env)->GetMethodID(env,
            connectionInfoClass, "<init>", "(JII)V");

    /*
     * Bail out now if we're not running as root
     */
    if (geteuid() != 0) {
        return (*env)->NewObject(env, connectionInfoClass,
                connectionInfoConstructor, 0, 0,
                VNET_API_ERROR_NOT_RUNNING_AS_ROOT);
    }

    if (rm->is_connected) {
        return (*env)->NewObject(env, connectionInfoClass,
                connectionInfoConstructor, 0, 0,
                VNET_API_ERROR_ALREADY_CONNECTED);
    }

    client_name = (*env)->GetStringUTFChars(env, clientName, 0);
    if (!client_name) {
        return (*env)->NewObject(env, connectionInfoClass,
                connectionInfoConstructor, 0, 0, VNET_API_ERROR_INVALID_VALUE);
    }

    rv = connect_to_vpe((char *) client_name);

    if (rv < 0)
        clib_warning("connection failed, rv %d", rv);

    (*env)->ReleaseStringUTFChars(env, clientName, client_name);

    return (*env)->NewObject(env, connectionInfoClass,
            connectionInfoConstructor, (jlong) jm->vl_input_queue,
            (jint) jm->my_client_index, (jint) rv);
}

JNIEXPORT jint JNICALL Java_org_openvpp_jvpp_JVppRegistryImpl_controlPing0(
        JNIEnv *env, jobject regstryObject) {
    jvpp_main_t * jm = &jvpp_main;
    vl_api_control_ping_t * mp;
    u32 my_context_id = vppjni_get_context_id(&jvpp_main);
    jvpp_registry_main_t * rm = &jvpp_registry_main;

    if (rm->registryObject == 0) {
        rm->registryObject = (*env)->NewGlobalRef(env, regstryObject);
    }
    if (rm->registryClass == 0) {
        rm->registryClass = (jclass) (*env)->NewGlobalRef(env,
                (*env)->GetObjectClass(env, regstryObject));
    }

    mp = vl_msg_api_alloc(sizeof(*mp));
    memset(mp, 0, sizeof(*mp));
    mp->_vl_msg_id = ntohs(VL_API_CONTROL_PING);
    mp->client_index = jm->my_client_index;
    mp->context = clib_host_to_net_u32(my_context_id);

    // send message:
    vl_msg_api_send_shmem(jm->vl_input_queue, (u8 *) &mp);
    return my_context_id;
}

JNIEXPORT void JNICALL Java_org_openvpp_jvpp_VppJNIConnection_clientDisconnect(
        JNIEnv *env, jclass clazz) {
    jvpp_registry_main_t * rm = &jvpp_registry_main;
    rm->is_connected = 0; // TODO make thread safe
    vl_client_disconnect_from_vlib();

    // cleanup:
    if (rm->registryObject) {
        (*env)->DeleteGlobalRef(env, rm->registryObject);
        rm->registryObject = 0;
    }
    if (rm->registryClass) {
        (*env)->DeleteGlobalRef(env, rm->registryClass);
        rm->registryClass = 0;
    }
}

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    jvpp_main_t * jm = &jvpp_main;
    jvpp_registry_main_t * rm = &jvpp_registry_main;
    JNIEnv* env;

    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) {
        return JNI_EVERSION;
    }

    rm->controlPingReplyClass = (jclass) (*env)->NewGlobalRef(env,
            (*env)->FindClass(env, "org/openvpp/jvpp/dto/ControlPingReply"));
    if ((*env)->ExceptionCheck(env)) {
        (*env)->ExceptionDescribe(env);
        clib_warning("Failed to cache class references\n");
        return JNI_ERR;
    }

    rm->callbackExceptionClass = (jclass) (*env)->NewGlobalRef(env,
            (*env)->FindClass(env, "org/openvpp/jvpp/VppCallbackException"));
    if ((*env)->ExceptionCheck(env)) {
        (*env)->ExceptionDescribe(env);
        return JNI_ERR;
    }

    jm->jvm = vm;
    return JNI_VERSION_1_8;
}

void JNI_OnUnload(JavaVM *vm, void *reserved) {
    jvpp_main_t * jm = &jvpp_main;
    JNIEnv* env;
    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) {
        return;
    }

    jm->jenv = NULL;
    jm->jvm = NULL;
}
