/*
 * Copyright (c) 2015 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>
#include <japi/vppjni_bridge_domain.h>

typedef struct {
    u8 * name;
    u32 value;
} name_sort_t;

typedef struct {
    u8 valid; // used in a vector of sw_interface_details_t

    u8 interface_name[64];
    u32 sw_if_index;
    u32 sup_sw_if_index;
    u32 l2_address_length;
    u8 l2_address[8];
    u8 admin_up_down;
    u8 link_up_down;
    u8 link_duplex;
    u8 link_speed;
    u32 sub_id;
    u8 sub_dot1ad;
    u8 sub_number_of_tags;
    u16 sub_outer_vlan_id;
    u16 sub_inner_vlan_id;
    u8 sub_exact_match;
    u8 sub_default;
    u8 sub_outer_vlan_id_any;
    u8 sub_inner_vlan_id_any;
    u32 vtr_op;
    u32 vtr_push_dot1q;
    u32 vtr_tag1;
    u32 vtr_tag2;
} sw_interface_details_t;

typedef struct {
    u8 * interface_name;
    u32 sw_if_index;
    /* 
     * Subinterface ID. A number 0-N to uniquely identify 
     * this subinterface under the super interface
     */
    u32 sub_id;

    /* 0 = dot1q, 1=dot1ad */
    u8 sub_dot1ad;

    /* Number of tags 0-2 */
    u8 sub_number_of_tags;
    u16 sub_outer_vlan_id;
    u16 sub_inner_vlan_id;
    u8 sub_exact_match;
    u8 sub_default;
    u8 sub_outer_vlan_id_any;
    u8 sub_inner_vlan_id_any;

    /* vlan tag rewrite */
    u32 vtr_op;
    u32 vtr_push_dot1q;
    u32 vtr_tag1;
    u32 vtr_tag2;
} sw_interface_subif_t;

typedef struct {
    u8 *desc;
} sw_if_config_t;

typedef struct {
    u32 ip;
    u8 prefix_length;
} ipv4_address_t;

typedef struct {
    u8 ip[16];
    u8 prefix_length;
} ipv6_address_t;

typedef struct {
  u64 ip4;
  u64 ip6;
  u64 unicast;
  u64 multicast;
  u64 broadcast;
  u64 discard;
  u64 fifo_full;
  u64 error;
  u64 unknown_proto;
  u64 miss;
} packet_counters_t;

typedef struct {
  u64 octets;
  packet_counters_t pkts;
} if_counters_t;

typedef struct {
  u8 valid;
  u32 sw_if_index;
  if_counters_t rx;
  if_counters_t tx;
} sw_interface_stats_t;

typedef struct {
    u32 src_address;
    u32 dst_address;
    u32 encap_vrf_id;
    u32 vni;
    u32 decap_next_index;
} vxlan_tunnel_details_t;


typedef struct {
  /* Context IDs */
  volatile u32 context_id_sent;
  volatile u32 context_id_received;

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

  /* To recycle pseudo-synchronous message code from vpp_api_test... */
  volatile u32 result_ready;
  volatile i32 retval;
  volatile u8 *shmem_result;

  /* thread cleanup */
  pthread_key_t cleanup_rx_thread_key;
  /* attachment of rx thread to java thread */
  JNIEnv *jenv;
  JavaVM *jvm;
  jclass jcls;
  jmethodID jmtdIfDetails;  // interfaceDetails method
  uword *callback_hash;     // map context_id => jobject
  uword *ping_hash;         // map ping context_id => msg type called

  /* Timestamp */
  clib_time_t clib_time;

  /* connected indication */
  u8 is_connected;

  /* context -> non-trivial reply hash */
  uword * reply_hash;
  u32 saved_reply_count;

  /* interface name map */
  uword * sw_if_index_by_interface_name;

  /* interface counters */
  sw_interface_stats_t * sw_if_stats_by_sw_if_index;

  /* interface table */
  sw_interface_details_t * sw_if_table;

  uword * sw_if_config_by_sw_if_index;

  /* interface indices of responses to one sw_if_dump request */
  u8 collect_indices;
  u32 * sw_if_dump_if_indices;

  /* program name, build_dir, version */
  u8 program_name[32];
  u8 build_directory[256];
  u8 version[32];
  u8 build_date[32];

  /* subinterface table */
  sw_interface_subif_t * sw_if_subif_table;

  /* used in ip_address_dump request and response handling */
  ipv4_address_t *ipv4_addresses;
  ipv6_address_t *ipv6_addresses;
  u8 is_ipv6;

  /* used in vxlan_tunnel_dump request and response handling */
  vxlan_tunnel_details_t *vxlan_tunnel_details;

  /* main heap */
  u8 * heap;

  /* convenience */
  unix_shared_memory_queue_t * vl_input_queue;
  api_main_t * api_main;
  u32 my_client_index;

  vjbd_main_t vjbd_main;
} vppjni_main_t;

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


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

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 f64 vppjni_time_now (vppjni_main_t *jm)
{
  return clib_time_now (&jm->clib_time);
}

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

#define __PACKED(x) x __attribute__((packed))

typedef __PACKED(struct _vl_api_generic_reply {
  u16 _vl_msg_id;
  u32 context;
  i32 retval;
  u8 data[0];
}) vl_api_generic_reply_t;

void vl_api_generic_reply_handler (vl_api_generic_reply_t *mp);

/* 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))

/* W: wait for results, with timeout */
#define W                                       \
  do {                                          \
    timeout = vppjni_time_now (jm) + 1.0;       \
                                                \
    while (vppjni_time_now (jm) < timeout) {    \
      if (jm->result_ready == 1) {              \
        return (jm->retval);                    \
      }                                         \
    }                                           \
    return -99;                                 \
} while(0);

/* WNR: wait for results, with timeout (without returning) */
#define WNR                                     \
  do {                                          \
    timeout = vppjni_time_now (jm) + 1.0;       \
                                                \
    rv = -99;                                   \
    while (vppjni_time_now (jm) < timeout) {    \
      if (jm->result_ready == 1) {              \
        rv = (jm->retval);                      \
        break;                                  \
      }                                         \
    }                                           \
} while(0);

#endif /* __included_vppjni_h__ */
