/*
 * 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.
 */
#ifndef __included_vppjni_h__
#define __included_vppjni_h__

#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/api_errno.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <jni.h>

typedef struct {
    /* Unique identifier used for matching replays with requests  */
    volatile u32 context_id;

    /* Spinlock */
    volatile u32 lock;
    u32 tag;

    /* Used for first control ping */
    // TODO better names?
    volatile u32 result_ready;
    volatile i32 retval;

    /* JNI Native Method Interface pointer for message handlers */
    JNIEnv *jenv;

    /* thread cleanup */
    pthread_key_t cleanup_rx_thread_key;

    /* JNI Invoke Interface pointer for attachment of rx thread to java thread */
    JavaVM *jvm;

    /* Callback object and class references enabling asynchronous Java calls */
    jobject callback;
    jclass callbackClass;

    /* Connected indication */
    volatile u8 is_connected;

    /* Convenience */
    unix_shared_memory_queue_t * vl_input_queue;
    u32 my_client_index;

} vppjni_main_t;

vppjni_main_t vppjni_main __attribute__((aligned (64)));

static inline u32 vppjni_get_context_id (vppjni_main_t * jm)
{
    return __sync_add_and_fetch (&jm->context_id, 1);
}

static inline void vppjni_lock (vppjni_main_t * jm, u32 tag)
{
    while (__sync_lock_test_and_set (&jm->lock, 1))
        ;
    jm->tag = tag;
}

static inline void vppjni_unlock (vppjni_main_t * jm)
{
    jm->tag = 0;
    CLIB_MEMORY_BARRIER();
    jm->lock = 0;
}

static inline int vppjni_sanity_check (vppjni_main_t * jm)
{
    if (!jm->is_connected)
        return VNET_API_ERROR_NOT_CONNECTED;
    return 0;
}

// TODO remove macros (code is now fully autogenerated)

/* M: construct, but don't yet send a message */
#define M(T,t)                                  \
do {                                            \
    jm->result_ready = 0;                         \
    mp = vl_msg_api_alloc(sizeof(*mp));           \
    memset (mp, 0, sizeof (*mp));                 \
    mp->_vl_msg_id = ntohs (VL_API_##T);          \
    mp->client_index = jm->my_client_index;       \
 } while(0);

#define M2(T,t,n)                               \
do {                                            \
    jm->result_ready = 0;                         \
    mp = vl_msg_api_alloc(sizeof(*mp)+(n));       \
    memset (mp, 0, sizeof (*mp));                 \
    mp->_vl_msg_id = ntohs (VL_API_##T);          \
    mp->client_index = jm->my_client_index;       \
 } while(0);

/* S: send a message */
#define S (vl_msg_api_send_shmem (jm->vl_input_queue, (u8 *)&mp))

#endif /* __included_vppjni_h__ */
