/*
 * 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 "io_fd_vpp_jvpp_VppJNIConnection.h"
#include "io_fd_vpp_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",
                    "(Lio/fd/vpp/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_io_fd_vpp_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,
            "io/fd/vpp/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_io_fd_vpp_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_io_fd_vpp_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, "io/fd/vpp/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, "io/fd/vpp/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;
}
