/*
 * 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_endianfun	      /* define message structures */
#include <vnet/session/session.api.h>
#undef vl_endianfun

#define vl_calcsizefun
#include <vnet/session/session.api.h>
#undef vl_calcsizefun

/* 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_config (&(vl_msg_api_msg_config_t){                              \
    .id = REPLY_MSG_ID_BASE + VL_API_##N,                                     \
    .name = #n,                                                               \
    .handler = vl_api_##n##_t_handler,                                        \
    .endian = vl_api_##n##_t_endian,                                          \
    .format_fn = vl_api_##n##_t_format,                                       \
    .size = sizeof (vl_api_##n##_t),                                          \
    .traced = 1,                                                              \
    .tojson = vl_api_##n##_t_tojson,                                          \
    .fromjson = vl_api_##n##_t_fromjson,                                      \
    .calc_size = vl_api_##n##_t_calc_size,                                    \
  });
  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) |
    (vcm->cfg.huge_page ? APP_OPTIONS_FLAGS_USE_HUGE_PAGE : 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:
 */
