/*
 *------------------------------------------------------------------
 * socket_client.c - API message handling over sockets, client code.
 *
 * Copyright (c) 2017 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.
 *------------------------------------------------------------------
 */

#include <stdio.h>
#define __USE_GNU
#define _GNU_SOURCE
#include <sys/socket.h>

#include <svm/ssvm.h>
#include <vlibmemory/socket_client.h>
#include <vlibmemory/memory_client.h>

#include <vlibmemory/vl_memory_msg_enum.h>

#define vl_typedefs		/* define message structures */
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_typedefs

#define vl_endianfun		/* define message structures */
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_endianfun

#define vl_calcsizefun
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_calcsizefun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...) clib_warning (__VA_ARGS__)
#define vl_printfun
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_printfun

socket_client_main_t socket_client_main;
__thread socket_client_main_t *socket_client_ctx = &socket_client_main;

/* Debug aid */
u32 vl (void *p) __attribute__ ((weak));

u32
vl (void *p)
{
  return vec_len (p);
}

static socket_client_main_t *
vl_socket_client_ctx_push (socket_client_main_t * ctx)
{
  socket_client_main_t *old = socket_client_ctx;
  socket_client_ctx = ctx;
  return old;
}

static void
vl_socket_client_ctx_pop (socket_client_main_t * old_ctx)
{
  socket_client_ctx = old_ctx;
}

static int
vl_socket_client_read_internal (socket_client_main_t * scm, int wait)
{
  u32 data_len = 0, msg_size;
  int n, current_rx_index;
  msgbuf_t *mbp = 0;
  f64 timeout;

  if (scm->socket_fd == 0)
    return -1;

  if (wait)
    timeout = clib_time_now (&scm->clib_time) + wait;

  while (1)
    {
      while (vec_len (scm->socket_rx_buffer) < sizeof (*mbp))
	{
	  current_rx_index = vec_len (scm->socket_rx_buffer);
	  vec_validate (scm->socket_rx_buffer, current_rx_index
			+ scm->socket_buffer_size - 1);
	  vec_set_len (scm->socket_rx_buffer, current_rx_index);
	  n = read (scm->socket_fd, scm->socket_rx_buffer + current_rx_index,
		    scm->socket_buffer_size);
	  if (n < 0)
	    {
	      if (errno == EAGAIN)
		continue;

	      clib_unix_warning ("socket_read");
	      return -1;
	    }
	  vec_inc_len (scm->socket_rx_buffer, n);
	}

#if CLIB_DEBUG > 1
      if (n > 0)
	clib_warning ("read %d bytes", n);
#endif

      mbp = (msgbuf_t *) (scm->socket_rx_buffer);
      data_len = ntohl (mbp->data_len);
      current_rx_index = vec_len (scm->socket_rx_buffer);
      vec_validate (scm->socket_rx_buffer, current_rx_index + data_len);
      vec_set_len (scm->socket_rx_buffer, current_rx_index);
      mbp = (msgbuf_t *) (scm->socket_rx_buffer);
      msg_size = data_len + sizeof (*mbp);

      while (vec_len (scm->socket_rx_buffer) < msg_size)
	{
	  n = read (scm->socket_fd,
		    scm->socket_rx_buffer + vec_len (scm->socket_rx_buffer),
		    msg_size - vec_len (scm->socket_rx_buffer));
	  if (n < 0)
	    {
	      if (errno == EAGAIN)
		continue;

	      clib_unix_warning ("socket_read");
	      return -1;
	    }
	  vec_inc_len (scm->socket_rx_buffer, n);
	}

      if (vec_len (scm->socket_rx_buffer) >= data_len + sizeof (*mbp))
	{
	  vl_msg_api_socket_handler ((void *) (mbp->data), data_len);

	  if (vec_len (scm->socket_rx_buffer) == data_len + sizeof (*mbp))
	    vec_set_len (scm->socket_rx_buffer, 0);
	  else
	    vec_delete (scm->socket_rx_buffer, data_len + sizeof (*mbp), 0);
	  mbp = 0;

	  /* Quit if we're out of data, and not expecting a ping reply */
	  if (vec_len (scm->socket_rx_buffer) == 0
	      && scm->control_pings_outstanding == 0)
	    break;
	}
      if (wait && clib_time_now (&scm->clib_time) >= timeout)
	return -1;
    }
  return 0;
}

int
vl_socket_client_read (int wait)
{
  return vl_socket_client_read_internal (socket_client_ctx, wait);
}

int
vl_socket_client_read2 (socket_client_main_t * scm, int wait)
{
  socket_client_main_t *old_ctx;
  int rv;

  old_ctx = vl_socket_client_ctx_push (scm);
  rv = vl_socket_client_read_internal (scm, wait);
  vl_socket_client_ctx_pop (old_ctx);
  return rv;
}

static int
vl_socket_client_write_internal (socket_client_main_t * scm)
{
  int n;

  msgbuf_t msgbuf = {
    .q = 0,
    .gc_mark_timestamp = 0,
    .data_len = htonl (scm->socket_tx_nbytes),
  };

  n = write (scm->socket_fd, &msgbuf, sizeof (msgbuf));
  if (n < sizeof (msgbuf))
    {
      clib_unix_warning ("socket write (msgbuf)");
      return -1;
    }

  n = write (scm->socket_fd, scm->socket_tx_buffer, scm->socket_tx_nbytes);
  if (n < scm->socket_tx_nbytes)
    {
      clib_unix_warning ("socket write (msg)");
      return -1;
    }

  return n;
}

int
vl_socket_client_write (void)
{
  return vl_socket_client_write_internal (socket_client_ctx);
}

int
vl_socket_client_write2 (socket_client_main_t * scm)
{
  socket_client_main_t *old_ctx;
  int rv;

  old_ctx = vl_socket_client_ctx_push (scm);
  rv = vl_socket_client_write_internal (scm);
  vl_socket_client_ctx_pop (old_ctx);
  return rv;
}

void *
vl_socket_client_msg_alloc2 (socket_client_main_t * scm, int nbytes)
{
  scm->socket_tx_nbytes = nbytes;
  return ((void *) scm->socket_tx_buffer);
}

void *
vl_socket_client_msg_alloc (int nbytes)
{
  return vl_socket_client_msg_alloc2 (socket_client_ctx, nbytes);
}

void
vl_socket_client_disconnect2 (socket_client_main_t * scm)
{
  if (vl_mem_client_is_connected ())
    {
      vl_client_disconnect_from_vlib_no_unmap ();
      ssvm_delete_memfd (&scm->memfd_segment);
    }
  if (scm->socket_fd && (close (scm->socket_fd) < 0))
    clib_unix_warning ("close");
  scm->socket_fd = 0;
}

void
vl_socket_client_disconnect (void)
{
  vl_socket_client_disconnect2 (socket_client_ctx);
}

void
vl_socket_client_enable_disable2 (socket_client_main_t * scm, int enable)
{
  scm->socket_enable = enable;
}

void
vl_socket_client_enable_disable (int enable)
{
  vl_socket_client_enable_disable2 (socket_client_ctx, enable);
}

static clib_error_t *
vl_sock_api_recv_fd_msg_internal (socket_client_main_t * scm, int fds[],
				  int n_fds, u32 wait)
{
  char msgbuf[16];
  char ctl[CMSG_SPACE (sizeof (int) * n_fds)
	   + CMSG_SPACE (sizeof (struct ucred))];
  struct msghdr mh = { 0 };
  struct iovec iov[1];
  ssize_t size = 0;
  struct ucred *cr = 0;
  struct cmsghdr *cmsg;
  pid_t pid __attribute__ ((unused));
  uid_t uid __attribute__ ((unused));
  gid_t gid __attribute__ ((unused));
  int socket_fd;
  f64 timeout;

  socket_fd = scm->client_socket.fd;

  iov[0].iov_base = msgbuf;
  iov[0].iov_len = 5;
  mh.msg_iov = iov;
  mh.msg_iovlen = 1;
  mh.msg_control = ctl;
  mh.msg_controllen = sizeof (ctl);

  clib_memset (ctl, 0, sizeof (ctl));

  if (wait != ~0)
    {
      timeout = clib_time_now (&scm->clib_time) + wait;
      while (size != 5 && clib_time_now (&scm->clib_time) < timeout)
	size = recvmsg (socket_fd, &mh, MSG_DONTWAIT);
    }
  else
    size = recvmsg (socket_fd, &mh, 0);

  if (size != 5)
    {
      return (size == 0) ? clib_error_return (0, "disconnected") :
	clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
				socket_fd);
    }

  cmsg = CMSG_FIRSTHDR (&mh);
  while (cmsg)
    {
      if (cmsg->cmsg_level == SOL_SOCKET)
	{
	  if (cmsg->cmsg_type == SCM_CREDENTIALS)
	    {
	      cr = (struct ucred *) CMSG_DATA (cmsg);
	      uid = cr->uid;
	      gid = cr->gid;
	      pid = cr->pid;
	    }
	  else if (cmsg->cmsg_type == SCM_RIGHTS)
	    {
	      clib_memcpy_fast (fds, CMSG_DATA (cmsg), sizeof (int) * n_fds);
	    }
	}
      cmsg = CMSG_NXTHDR (&mh, cmsg);
    }
  return 0;
}

clib_error_t *
vl_sock_api_recv_fd_msg (int socket_fd, int fds[], int n_fds, u32 wait)
{
  return vl_sock_api_recv_fd_msg_internal (socket_client_ctx, fds, n_fds,
					   wait);
}

clib_error_t *
vl_sock_api_recv_fd_msg2 (socket_client_main_t * scm, int socket_fd,
			  int fds[], int n_fds, u32 wait)
{
  socket_client_main_t *old_ctx;
  clib_error_t *error;

  old_ctx = vl_socket_client_ctx_push (scm);
  error = vl_sock_api_recv_fd_msg_internal (scm, fds, n_fds, wait);
  vl_socket_client_ctx_pop (old_ctx);
  return error;
}

static void vl_api_sock_init_shm_reply_t_handler
  (vl_api_sock_init_shm_reply_t * mp)
{
  socket_client_main_t *scm = socket_client_ctx;
  ssvm_private_t *memfd = &scm->memfd_segment;
  i32 retval = ntohl (mp->retval);
  api_main_t *am = vlibapi_get_main ();
  clib_error_t *error;
  int my_fd = -1;
  u8 *new_name;

  if (retval)
    {
      clib_warning ("failed to init shmem");
      return;
    }

  /*
   * Check the socket for the magic fd
   */
  error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 1, 5);
  if (error)
    {
      clib_error_report (error);
      retval = -99;
      return;
    }

  clib_memset (memfd, 0, sizeof (*memfd));
  memfd->fd = my_fd;

  /* Note: this closes memfd.fd */
  retval = ssvm_client_init_memfd (memfd);
  if (retval)
    clib_warning ("WARNING: segment map returned %d", retval);

  /*
   * Pivot to the memory client segment that vpp just created
   */
  am->vlib_rp = (void *) (memfd->requested_va + MMAP_PAGESIZE);
  am->shmem_hdr = (void *) am->vlib_rp->user_ctx;

  new_name = format (0, "%v[shm]%c", scm->name, 0);
  vl_client_install_client_message_handlers ();
  if (scm->want_shm_pthread)
    {
      vl_client_connect_to_vlib_no_map ("pvt", (char *) new_name,
					32 /* input_queue_length */ );
    }
  else
    {
      vl_client_connect_to_vlib_no_rx_pthread_no_map ("pvt",
						      (char *) new_name, 32
						      /* input_queue_length */
	);
    }
  vl_socket_client_enable_disable (0);
  vec_free (new_name);
}

static void
vl_api_sockclnt_create_reply_t_handler (vl_api_sockclnt_create_reply_t * mp)
{
  socket_client_main_t *scm = socket_client_ctx;
  if (!mp->response)
    {
      scm->socket_enable = 1;
      scm->client_index = clib_net_to_host_u32 (mp->index);
    }
}

#define foreach_sock_client_api_msg             		\
_(SOCKCLNT_CREATE_REPLY, sockclnt_create_reply)			\
_(SOCK_INIT_SHM_REPLY, sock_init_shm_reply)     		\

static void
noop_handler (void *notused)
{
}

void
vl_sock_client_install_message_handlers (void)
{

#define _(N, n)                                                               \
  vl_msg_api_set_handlers (                                                   \
    VL_API_##N, #n, vl_api_##n##_t_handler, noop_handler,                     \
    vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0,  \
    vl_api_##n##_t_print_json, vl_api_##n##_t_tojson,                         \
    vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size);
  foreach_sock_client_api_msg;
#undef _
}

int
vl_socket_client_connect_internal (socket_client_main_t * scm,
				   char *socket_path, char *client_name,
				   u32 socket_buffer_size)
{
  vl_api_sockclnt_create_t *mp;
  clib_socket_t *sock;
  clib_error_t *error;

  /* Already connected? */
  if (scm->socket_fd)
    return (-2);

  /* bogus call? */
  if (socket_path == 0 || client_name == 0)
    return (-3);

  sock = &scm->client_socket;
  sock->config = socket_path;
  sock->flags = CLIB_SOCKET_F_IS_CLIENT;

  if ((error = clib_socket_init (sock)))
    {
      clib_error_report (error);
      return (-1);
    }

  vl_sock_client_install_message_handlers ();

  scm->socket_fd = sock->fd;
  scm->socket_buffer_size = socket_buffer_size ? socket_buffer_size :
    SOCKET_CLIENT_DEFAULT_BUFFER_SIZE;
  vec_validate (scm->socket_tx_buffer, scm->socket_buffer_size - 1);
  vec_validate (scm->socket_rx_buffer, scm->socket_buffer_size - 1);
  vec_set_len (scm->socket_rx_buffer, 0);
  vec_set_len (scm->socket_tx_buffer, 0);
  scm->name = format (0, "%s", client_name);

  mp = vl_socket_client_msg_alloc2 (scm, sizeof (*mp));
  mp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE);
  strncpy ((char *) mp->name, client_name, sizeof (mp->name) - 1);
  mp->name[sizeof (mp->name) - 1] = 0;
  mp->context = 0xfeedface;

  clib_time_init (&scm->clib_time);

  if (vl_socket_client_write_internal (scm) <= 0)
    return (-1);

  if (vl_socket_client_read_internal (scm, 5))
    return (-1);

  return (0);
}

int
vl_socket_client_connect (char *socket_path, char *client_name,
			  u32 socket_buffer_size)
{
  return vl_socket_client_connect_internal (socket_client_ctx, socket_path,
					    client_name, socket_buffer_size);
}

int
vl_socket_client_connect2 (socket_client_main_t * scm, char *socket_path,
			   char *client_name, u32 socket_buffer_size)
{
  socket_client_main_t *old_ctx;
  int rv;

  old_ctx = vl_socket_client_ctx_push (scm);
  rv = vl_socket_client_connect_internal (socket_client_ctx, socket_path,
					  client_name, socket_buffer_size);
  vl_socket_client_ctx_pop (old_ctx);
  return rv;
}

int
vl_socket_client_init_shm_internal (socket_client_main_t * scm,
				    vl_api_shm_elem_config_t * config,
				    int want_pthread)
{
  vl_api_sock_init_shm_t *mp;
  int rv, i;
  u64 *cfg;

  scm->want_shm_pthread = want_pthread;

  mp = vl_socket_client_msg_alloc2 (scm, sizeof (*mp) +
				    vec_len (config) * sizeof (u64));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_SOCK_INIT_SHM);
  mp->client_index = clib_host_to_net_u32 (scm->client_index);
  mp->requested_size = 64 << 20;

  if (config)
    {
      for (i = 0; i < vec_len (config); i++)
	{
	  cfg = (u64 *) & config[i];
	  mp->configs[i] = *cfg;
	}
      mp->nitems = vec_len (config);
    }
  rv = vl_socket_client_write_internal (scm);
  if (rv <= 0)
    return rv;

  if (vl_socket_client_read_internal (scm, 1))
    return -1;

  return 0;
}

int
vl_socket_client_init_shm (vl_api_shm_elem_config_t * config,
			   int want_pthread)
{
  return vl_socket_client_init_shm_internal (socket_client_ctx, config,
					     want_pthread);
}

int
vl_socket_client_init_shm2 (socket_client_main_t * scm,
			    vl_api_shm_elem_config_t * config,
			    int want_pthread)
{
  socket_client_main_t *old_ctx;
  int rv;

  old_ctx = vl_socket_client_ctx_push (scm);
  rv = vl_socket_client_init_shm_internal (socket_client_ctx, config,
					   want_pthread);
  vl_socket_client_ctx_pop (old_ctx);
  return rv;
}

clib_error_t *
vl_socket_client_recv_fd_msg2 (socket_client_main_t * scm, int fds[],
			       int n_fds, u32 wait)
{
  if (!scm->socket_fd)
    return clib_error_return (0, "no socket");
  return vl_sock_api_recv_fd_msg_internal (scm, fds, n_fds, wait);
}

clib_error_t *
vl_socket_client_recv_fd_msg (int fds[], int n_fds, u32 wait)
{
  return vl_socket_client_recv_fd_msg2 (socket_client_ctx, fds, n_fds, wait);
}

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