/*
 * Copyright (c) 2018-2019 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this
 * 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 <vcl/vcl_private.h>
#include <vlibmemory/api.h>

#include <vnet/format_fns.h>
#include <vnet/session/session.api_enum.h>
#include <vnet/session/session.api_types.h>

#define REPLY_MSG_ID_BASE msg_id_base

static u16 msg_id_base;

static u8 *
format_api_error (u8 * s, va_list * args)
{
  i32 error = va_arg (*args, u32);
  uword *p;

  p = hash_get (vcm->error_string_by_error_number, -error);

  if (p)
    s = format (s, "%s (%d)", p[0], error);
  else
    s = format (s, "%d", error);
  return s;
}

static void
  vl_api_session_enable_disable_reply_t_handler
  (vl_api_session_enable_disable_reply_t * mp)
{
  vcl_worker_t *wrk = vcl_worker_get (0);

  if (mp->retval)
    {
      clib_warning ("VCL<%d>: session_enable_disable failed: %U", getpid (),
		    format_api_error, ntohl (mp->retval));
    }
  else
    wrk->bapi_app_state = STATE_APP_ENABLED;
}

static void
vl_api_app_attach_reply_t_handler (vl_api_app_attach_reply_t * mp)
{
  vcl_worker_t *wrk = vcl_worker_get (0);
  u64 segment_handle;
  int *fds = 0, i, rv;
  u32 n_fds = 0;
  char *segment_name = 0;

  if (mp->retval)
    {
      VERR ("attach failed: %U", format_api_error, ntohl (mp->retval));
      goto failed;
    }

  vcl_set_worker_index (0);

  segment_handle = clib_net_to_host_u64 (mp->segment_handle);
  if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
    {
      VERR ("invalid segment handle");
      goto failed;
    }

  if (mp->n_fds)
    {
      vec_validate (fds, mp->n_fds);
      if (vl_socket_client_recv_fd_msg2 (&wrk->bapi_sock_ctx, fds, mp->n_fds,
					 5))
	goto failed;

      if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
	if (vcl_segment_attach (vcl_vpp_worker_segment_handle (0),
				"vpp-mq-seg", SSVM_SEGMENT_MEMFD,
				fds[n_fds++]))
	  goto failed;

      if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
	{
	  segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
	  rv =
	    vcl_segment_attach (segment_handle, segment_name,
				SSVM_SEGMENT_MEMFD, fds[n_fds++]);
	  vec_free (segment_name);
	  if (rv != 0)
	    goto failed;
	}

      vcl_segment_attach_mq (segment_handle, mp->app_mq, 0,
			     &wrk->app_event_queue);

      if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
	{
	  svm_msg_q_set_eventfd (wrk->app_event_queue, fds[n_fds]);
	  vcl_mq_epoll_add_evfd (wrk, wrk->app_event_queue);
	  n_fds++;
	}

      vcl_segment_discover_mqs (vcl_vpp_worker_segment_handle (0), fds + n_fds,
				mp->n_fds - n_fds);
      vcl_segment_attach_mq (vcl_vpp_worker_segment_handle (0),
			     mp->vpp_ctrl_mq, mp->vpp_ctrl_mq_thread,
			     &wrk->ctrl_mq);
      vcm->ctrl_mq = wrk->ctrl_mq;

      vec_free (fds);
    }
  else
    {
      segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
      rv =
	vcl_segment_attach (segment_handle, segment_name, SSVM_SEGMENT_SHM,
			    -1);
      vec_free (segment_name);
      if (rv != 0)
	goto failed;
    }

  vcm->app_index = clib_net_to_host_u32 (mp->app_index);
  wrk->bapi_app_state = STATE_APP_ATTACHED;
  return;

failed:
  wrk->bapi_app_state = STATE_APP_FAILED;
  for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
    close (fds[i]);
  vec_free (fds);
}

static void
vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t *
					   mp)
{
  int n_fds = 0, *fds = 0, i, rv;
  u64 segment_handle;
  vcl_worker_t *wrk;
  u32 wrk_index;
  char *segment_name = 0;

  if (!mp->is_add)
    return;

  wrk_index = mp->context;
  wrk = vcl_worker_get_if_valid (wrk_index);
  if (!wrk)
    return;

  if (mp->retval)
    {
      clib_warning ("VCL<%d>: add/del worker failed: %U", getpid (),
		    format_api_error, ntohl (mp->retval));
      goto failed;
    }

  vcl_set_worker_index (wrk_index);
  wrk->vpp_wrk_index = clib_net_to_host_u32 (mp->wrk_index);
  wrk->ctrl_mq = vcm->ctrl_mq;

  segment_handle = clib_net_to_host_u64 (mp->segment_handle);
  if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
    {
      clib_warning ("invalid segment handle");
      goto failed;
    }

  if (mp->n_fds)
    {
      vec_validate (fds, mp->n_fds);
      if (vl_socket_client_recv_fd_msg2 (&wrk->bapi_sock_ctx, fds, mp->n_fds,
					 5))
	goto failed;

      if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
	if (vcl_segment_attach (vcl_vpp_worker_segment_handle (wrk_index),
				"vpp-worker-seg", SSVM_SEGMENT_MEMFD,
				fds[n_fds++]))
	  goto failed;

      if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
	{
	  segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
	  rv =
	    vcl_segment_attach (segment_handle, segment_name,
				SSVM_SEGMENT_MEMFD, fds[n_fds++]);
	  vec_free (segment_name);
	  if (rv != 0)
	    goto failed;
	}

      vcl_segment_attach_mq (segment_handle, mp->app_event_queue_address, 0,
			     &wrk->app_event_queue);

      if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
	{
	  svm_msg_q_set_eventfd (wrk->app_event_queue, fds[n_fds]);
	  vcl_mq_epoll_add_evfd (wrk, wrk->app_event_queue);
	  n_fds++;
	}

      vec_free (fds);
    }
  else
    {
      segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
      rv =
	vcl_segment_attach (segment_handle, segment_name, SSVM_SEGMENT_SHM,
			    -1);
      vec_free (segment_name);
      if (rv != 0)
	goto failed;
    }
  wrk->bapi_app_state = STATE_APP_READY;
  VDBG (0, "worker %u vpp-worker %u added", wrk_index, wrk->vpp_wrk_index);
  return;

failed:
  wrk->bapi_app_state = STATE_APP_FAILED;
  for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
    close (fds[i]);
  vec_free (fds);
}

static void
vl_api_app_add_cert_key_pair_reply_t_handler (
  vl_api_app_add_cert_key_pair_reply_t *mp)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();

  if (mp->retval)
    {
      VDBG (0, "Adding cert and key failed: %U", format_api_error,
	    ntohl (mp->retval));
      return;
    }
  wrk->bapi_return = clib_net_to_host_u32 (mp->index);
  wrk->bapi_app_state = STATE_APP_READY;
}

static void
vl_api_app_del_cert_key_pair_reply_t_handler (
  vl_api_app_del_cert_key_pair_reply_t *mp)
{
  if (mp->retval)
    {
      VDBG (0, "Deleting cert and key failed: %U", format_api_error,
	    ntohl (mp->retval));
      return;
    }
}

#define foreach_sock_msg                                                      \
  _ (SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply)              \
  _ (APP_ATTACH_REPLY, app_attach_reply)                                      \
  _ (APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply)                \
  _ (APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply)                \
  _ (APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply)

#define vl_print(handle, ...) fformat (handle, __VA_ARGS__)
#define vl_endianfun	      /* define message structures */
#include <vnet/session/session.api.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_printfun
#include <vnet/session/session.api.h>
#undef vl_printfun

#define vl_api_version(n, v) static u32 api_version = v;
#include <vnet/session/session.api.h>
#undef vl_api_version

static void
vcl_bapi_hookup (void)
{
  u8 *msg_base_lookup_name = format (0, "session_%08x%c", api_version, 0);

  REPLY_MSG_ID_BASE =
    vl_client_get_first_plugin_msg_id ((char *) msg_base_lookup_name);

  vec_free (msg_base_lookup_name);

  if (REPLY_MSG_ID_BASE == (u16) ~0)
    return;

#define _(N, n)                                                               \
  vl_msg_api_set_handlers (                                                   \
    REPLY_MSG_ID_BASE + VL_API_##N, #n, vl_api_##n##_t_handler,               \
    vl_noop_handler, vl_api_##n##_t_endian, vl_api_##n##_t_print,             \
    sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_print_json,                    \
    vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
  foreach_sock_msg;
#undef _
}

/*
 * VPP-API message functions
 */
static void
vcl_bapi_send_session_enable_disable (u8 is_enable)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  vl_api_session_enable_disable_t *bmp;
  bmp = vl_msg_api_alloc (sizeof (*bmp));
  memset (bmp, 0, sizeof (*bmp));

  bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_SESSION_ENABLE_DISABLE);
  bmp->client_index = wrk->api_client_handle;
  bmp->context = htonl (0xfeedface);
  bmp->is_enable = is_enable;
  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
}

void
vcl_bapi_send_attach (void)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  u8 tls_engine = CRYPTO_ENGINE_OPENSSL;
  vl_api_app_attach_t *bmp;
  u8 nsid_len = vec_len (vcm->cfg.namespace_id);
  u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
		     vcm->cfg.app_proxy_transport_udp);

  tls_engine = vcm->cfg.tls_engine ? vcm->cfg.tls_engine : tls_engine;

  bmp = vl_msg_api_alloc (sizeof (*bmp));
  memset (bmp, 0, sizeof (*bmp));

  bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_ATTACH);
  bmp->client_index = wrk->api_client_handle;
  bmp->context = htonl (0xfeedface);
  bmp->options[APP_OPTIONS_FLAGS] =
    APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
    (vcm->cfg.app_scope_local ? APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE : 0) |
    (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) |
    (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0) |
    (vcm->cfg.use_mq_eventfd ? APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD : 0);
  bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
    (u64) ((vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
	   (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0));
  bmp->options[APP_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
  bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
  bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
  bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
  bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
    vcm->cfg.preallocated_fifo_pairs;
  bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
  bmp->options[APP_OPTIONS_TLS_ENGINE] = tls_engine;
  if (nsid_len)
    {
      vl_api_vec_to_api_string (vcm->cfg.namespace_id, &bmp->namespace_id);
      bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
    }
  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
}

void
vcl_bapi_send_detach (void)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  vl_api_application_detach_t *bmp;
  bmp = vl_msg_api_alloc (sizeof (*bmp));
  memset (bmp, 0, sizeof (*bmp));

  bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APPLICATION_DETACH);
  bmp->client_index = wrk->api_client_handle;
  bmp->context = htonl (0xfeedface);
  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
}

static void
vcl_bapi_send_app_worker_add_del (u8 is_add)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  vl_api_app_worker_add_del_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  memset (mp, 0, sizeof (*mp));

  mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_WORKER_ADD_DEL);
  mp->client_index = wrk->api_client_handle;
  mp->app_index = clib_host_to_net_u32 (vcm->app_index);
  mp->context = wrk->wrk_index;
  mp->is_add = is_add;
  if (!is_add)
    mp->wrk_index = clib_host_to_net_u32 (wrk->vpp_wrk_index);

  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
}

static void
vcl_bapi_send_child_worker_del (vcl_worker_t * child_wrk)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  vl_api_app_worker_add_del_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  memset (mp, 0, sizeof (*mp));

  mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_WORKER_ADD_DEL);
  mp->client_index = wrk->api_client_handle;
  mp->app_index = clib_host_to_net_u32 (vcm->app_index);
  mp->context = wrk->wrk_index;
  mp->is_add = 0;
  mp->wrk_index = clib_host_to_net_u32 (child_wrk->vpp_wrk_index);

  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
}

static void
vcl_bapi_send_app_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  u32 cert_len = ckpair->cert_len;
  u32 key_len = ckpair->key_len;
  vl_api_app_add_cert_key_pair_t *bmp;

  bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len);
  clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len);

  bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_ADD_CERT_KEY_PAIR);
  bmp->client_index = wrk->api_client_handle;
  bmp->context = wrk->wrk_index;
  bmp->cert_len = clib_host_to_net_u16 (cert_len);
  bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len);
  clib_memcpy_fast (bmp->certkey, ckpair->cert, cert_len);
  clib_memcpy_fast (bmp->certkey + cert_len, ckpair->key, key_len);

  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
}

static void
vcl_bapi_send_app_del_cert_key_pair (u32 ckpair_index)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  vl_api_app_del_cert_key_pair_t *bmp;
  bmp = vl_msg_api_alloc (sizeof (*bmp));
  clib_memset (bmp, 0, sizeof (*bmp));

  bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_DEL_CERT_KEY_PAIR);
  bmp->client_index = wrk->api_client_handle;
  bmp->context = wrk->wrk_index;
  bmp->index = clib_host_to_net_u32 (ckpair_index);
  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
}

u32
vcl_bapi_max_nsid_len (void)
{
  vl_api_app_attach_t *mp;
  return (sizeof (mp->namespace_id) - 1);
}

static void
vcl_bapi_init_error_string_table (void)
{
  vcm->error_string_by_error_number = hash_create (0, sizeof (uword));

#define _(n, v, s) hash_set (vcm->error_string_by_error_number, -v, s);
  foreach_vnet_api_error;
#undef _

  hash_set (vcm->error_string_by_error_number, 99, "Misc");
}

static void
vcl_bapi_cleanup (void)
{
  socket_client_main_t *scm = &socket_client_main;
  api_main_t *am = vlibapi_get_main ();

  am->my_client_index = ~0;
  am->my_registration = 0;
  am->vl_input_queue = 0;
  am->msg_index_by_name_and_crc = 0;
  scm->socket_fd = 0;

  vl_client_api_unmap ();
}

static int
vcl_bapi_connect_to_vpp (void)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  vppcom_cfg_t *vcl_cfg = &vcm->cfg;
  int rv = VPPCOM_OK;
  api_main_t *am;
  u8 *wrk_name;

  wrk_name = format (0, "%v-wrk-%u%c", vcm->app_name, wrk->wrk_index, 0);

  /* Make sure api is cleaned up in case this is a connect from a
   * forked worker */
  vcl_bapi_cleanup ();

  vlibapi_set_main (&wrk->bapi_api_ctx);
  vlibapi_set_memory_client_main (&wrk->bapi_mem_ctx);

  if (!vcl_cfg->vpp_bapi_socket_name)
    {
      rv = VPPCOM_EINVAL;
      goto error;
    }

  if (vl_socket_client_connect2 (&wrk->bapi_sock_ctx,
				 (char *) vcl_cfg->vpp_bapi_socket_name,
				 (char *) wrk_name,
				 0 /* default rx/tx buffer */ ))
    {
      VERR ("app (%s) socket connect failed!", wrk_name);
      rv = VPPCOM_ECONNREFUSED;
      goto error;
    }

  if (vl_socket_client_init_shm2 (&wrk->bapi_sock_ctx, 0,
				  1 /* want_pthread */ ))
    {
      VERR ("app (%s) init shm failed!", wrk_name);
      rv = VPPCOM_ECONNREFUSED;
      goto error;
    }
  vcl_bapi_hookup ();

  am = vlibapi_get_main ();
  wrk->vl_input_queue = am->shmem_hdr->vl_input_queue;
  wrk->api_client_handle = (u32) am->my_client_index;

  VDBG (0, "app (%s) is connected to VPP!", wrk_name);
  vcl_evt (VCL_EVT_INIT, vcm);

error:
  vec_free (wrk_name);
  return rv;
}

void
vcl_bapi_disconnect_from_vpp (void)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  vppcom_cfg_t *vcl_cfg = &vcm->cfg;

  if (vcl_cfg->vpp_bapi_socket_name)
    vl_socket_client_disconnect2 (&wrk->bapi_sock_ctx);
  else
    vl_client_disconnect_from_vlib ();
}

static const char *
vcl_bapi_app_state_str (vcl_bapi_app_state_t state)
{
  char *st;

  switch (state)
    {
    case STATE_APP_START:
      st = "STATE_APP_START";
      break;

    case STATE_APP_CONN_VPP:
      st = "STATE_APP_CONN_VPP";
      break;

    case STATE_APP_ENABLED:
      st = "STATE_APP_ENABLED";
      break;

    case STATE_APP_ATTACHED:
      st = "STATE_APP_ATTACHED";
      break;

    default:
      st = "UNKNOWN_APP_STATE";
      break;
    }

  return st;
}

static int
vcl_bapi_wait_for_wrk_state_change (vcl_bapi_app_state_t app_state)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  f64 timeout = clib_time_now (&wrk->clib_time) + vcm->cfg.app_timeout;

  while (clib_time_now (&wrk->clib_time) < timeout)
    {
      if (wrk->bapi_app_state == app_state)
	return VPPCOM_OK;
      if (wrk->bapi_app_state == STATE_APP_FAILED)
	return VPPCOM_ECONNABORTED;
    }
  VDBG (0, "timeout waiting for state %s, current state %d",
	vcl_bapi_app_state_str (app_state), wrk->bapi_app_state);
  vcl_evt (VCL_EVT_SESSION_TIMEOUT, vcm, bapi_app_state);

  return VPPCOM_ETIMEDOUT;
}

static int
vcl_bapi_session_enable (void)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  int rv;

  if (wrk->bapi_app_state != STATE_APP_ENABLED)
    {
      vcl_bapi_send_session_enable_disable (1 /* is_enabled == TRUE */ );
      rv = vcl_bapi_wait_for_wrk_state_change (STATE_APP_ENABLED);
      if (PREDICT_FALSE (rv))
	{
	  VDBG (0, "application session enable timed out! returning %d (%s)",
		rv, vppcom_retval_str (rv));
	  return rv;
	}
    }
  return VPPCOM_OK;
}

static int
vcl_bapi_init (void)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  int rv;

  wrk->bapi_app_state = STATE_APP_START;
  vcl_bapi_init_error_string_table ();
  rv = vcl_bapi_connect_to_vpp ();
  if (rv)
    {
      VERR ("couldn't connect to VPP!");
      return rv;
    }
  VDBG (0, "sending session enable");
  rv = vcl_bapi_session_enable ();
  if (rv)
    {
      VERR ("vppcom_app_session_enable() failed!");
      return rv;
    }

  return 0;
}

int
vcl_bapi_attach (void)
{
  int rv;

  /* API hookup and connect to VPP */
  if ((rv = vcl_bapi_init ()))
    return rv;

  vcl_bapi_send_attach ();
  rv = vcl_bapi_wait_for_wrk_state_change (STATE_APP_ATTACHED);
  if (PREDICT_FALSE (rv))
    {
      VDBG (0, "application attach timed out! returning %d (%s)", rv,
	    vppcom_retval_str (rv));
      return rv;
    }

  return 0;
}

int
vcl_bapi_app_worker_add (void)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();

  if (vcl_bapi_connect_to_vpp ())
    return -1;

  wrk->bapi_app_state = STATE_APP_ADDING_WORKER;
  vcl_bapi_send_app_worker_add_del (1 /* is_add */ );
  if (vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY))
    return -1;
  return 0;
}

void
vcl_bapi_app_worker_del (vcl_worker_t * wrk)
{
  /* Notify vpp that the worker is going away */
  if (wrk->wrk_index == vcl_get_worker_index ())
    vcl_bapi_send_app_worker_add_del (0 /* is_add */ );
  else
    vcl_bapi_send_child_worker_del (wrk);

  /* Disconnect the binary api */
  if (vec_len (vcm->workers) == 1)
    vcl_bapi_disconnect_from_vpp ();
  else
    vl_client_send_disconnect (1 /* vpp should cleanup */ );
}

int
vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds)
{
  clib_error_t *err;

  if ((err = vl_socket_client_recv_fd_msg2 (&wrk->bapi_sock_ctx, fds, n_fds,
					    5)))
    {
      clib_error_report (err);
      return -1;
    }

  return 0;
}

int
vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();

  if (ckpair->key_len == 0 || ckpair->key_len == ~0)
    return VPPCOM_EINVAL;

  vcl_bapi_send_app_add_cert_key_pair (ckpair);
  wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA;
  vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY);
  if (wrk->bapi_app_state == STATE_APP_READY)
    return wrk->bapi_return;
  return VPPCOM_EFAULT;
}

int
vcl_bapi_del_cert_key_pair (u32 ckpair_index)
{
  /* Don't wait for reply */
  vcl_bapi_send_app_del_cert_key_pair (ckpair_index);
  return 0;
}

int
vcl_bapi_worker_set (void)
{
  vcl_worker_t *wrk = vcl_worker_get_current ();
  int i;

  /* Find the first worker with the same pid */
  for (i = 0; i < vec_len (vcm->workers); i++)
    {
      if (i == wrk->wrk_index)
	continue;
      if (vcm->workers[i].current_pid == wrk->current_pid)
	{
	  wrk->vl_input_queue = vcm->workers[i].vl_input_queue;
	  wrk->api_client_handle = vcm->workers[i].api_client_handle;
	  return 0;
	}
    }
  return -1;
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
