/*
 *------------------------------------------------------------------
 * sockclnt_vlib.c
 *
 * Copyright (c) 2009 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 <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <vppinfra/byte_order.h>
#include <netdb.h>

#include <fcntl.h>
#include <sys/stat.h>

#include <vlibmemory/api.h>
#include <vlibsocket/api.h>

#include <vlibsocket/vl_socket_msg_enum.h>

#define vl_typedefs		/* define message structures */
#include <vlibsocket/vl_socket_api_h.h>
#undef vl_typedefs

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

/* instantiate all the endian swap functions we know about */
#define vl_endianfun
#include <vlibsocket/vl_socket_api_h.h>
#undef vl_endianfun

static void
vl_api_sockclnt_create_reply_t_handler (vl_api_sockclnt_create_reply_t * mp)
{
  vl_api_registration_t *rp = socket_main.current_rp;

  rp->server_handle = mp->handle;
  rp->server_index = mp->index;
}

static void
vl_api_sockclnt_delete_reply_t_handler (vl_api_sockclnt_delete_reply_t * mp)
{
  unix_main_t *um = &unix_main;
  unix_file_t *uf = socket_main.current_uf;
  vl_api_registration_t *rp = socket_main.current_rp;

  unix_file_del (um, uf);
  vl_free_socket_registration_index (rp->vl_api_registration_pool_index);
}

u32
sockclnt_open_index (char *client_name, char *hostname, int port)
{
  vl_api_registration_t *rp;
  unix_main_t *um = &unix_main;
  unix_file_t template = { 0 };
  int sockfd;
  int one = 1;
  int rv;
  struct sockaddr_in serv_addr;
  struct hostent *server;
  vl_api_sockclnt_create_t *mp;
  char my_hostname[64];

  server = gethostbyname (hostname);
  if (server == NULL)
    {
      clib_warning ("Couldn't translate server name %s", hostname);
      return ~0;
    }

  /* Set up non-blocking server socket on CLIENT_API_SERVER_PORT */
  sockfd = socket (AF_INET, SOCK_STREAM, 0);

  if (sockfd < 0)
    {
      clib_unix_warning ("socket");
      return ~0;
    }

  bzero ((char *) &serv_addr, sizeof (serv_addr));
  serv_addr.sin_family = AF_INET;
  bcopy ((char *) server->h_addr,
	 (char *) &serv_addr.sin_addr.s_addr, server->h_length);
  serv_addr.sin_port = htons (port);

  if (connect (sockfd, (const void *) &serv_addr, sizeof (serv_addr)) < 0)
    {
      clib_unix_warning ("Connect failure to (%s, %d)", hostname, port);
      return ~0;
    }

  rv = ioctl (sockfd, FIONBIO, &one);
  if (rv < 0)
    {
      clib_unix_warning ("FIONBIO");
      return ~0;
    }

  pool_get (socket_main.registration_pool, rp);
  memset (rp, 0, sizeof (*rp));
  rp->registration_type = REGISTRATION_TYPE_SOCKET_CLIENT;
  rp->vl_api_registration_pool_index = rp - socket_main.registration_pool;

  template.read_function = vl_socket_read_ready;
  template.write_function = vl_socket_write_ready;
  template.file_descriptor = sockfd;
  template.private_data = rp - socket_main.registration_pool;

  rp->unix_file_index = unix_file_add (um, &template);
  rp->name = format (0, "%s:%d", hostname, port);

  mp = vl_msg_api_alloc (sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_SOCKCLNT_CREATE);
  mp->context = rp - socket_main.registration_pool;

  if (gethostname (my_hostname, sizeof (my_hostname)) < 0)
    {
      clib_unix_warning ("gethostname");
      strncpy (my_hostname, "unknown!", sizeof (my_hostname) - 1);
    }
  strncpy ((char *) mp->name, my_hostname, sizeof (mp->name) - 1);

  vl_msg_api_send (rp, (u8 *) mp);
  return rp - socket_main.registration_pool;
}

void
sockclnt_close_index (u32 index)
{
  vl_api_sockclnt_delete_t *mp;
  vl_api_registration_t *rp;

  /* Don't crash / assert if fed garbage */
  if (pool_is_free_index (socket_main.registration_pool, index))
    {
      clib_warning ("registration_pool index %d already free", index);
      return;
    }
  rp = pool_elt_at_index (socket_main.registration_pool, index);

  mp = vl_msg_api_alloc (sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_SOCKCLNT_DELETE);
  mp->handle = rp->server_handle;
  mp->index = rp->server_index;
  vl_msg_api_send (rp, (u8 *) mp);
}

vl_api_registration_t *
sockclnt_get_registration (u32 index)
{
  return pool_elt_at_index (socket_main.registration_pool, index);
}

/*
 * Both rx and tx msgs MUST be initialized, or we'll have
 * precisely no idea how many bytes to write into the API trace...
 */
#define foreach_sockclnt_api_msg                        \
_(SOCKCLNT_CREATE_REPLY, sockclnt_create_reply)         \
_(SOCKCLNT_DELETE_REPLY, sockclnt_delete_reply)


static clib_error_t *
sockclnt_vlib_api_init (vlib_main_t * vm)
{
#define _(N,n)                                                  \
    vl_msg_api_set_handlers(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);
  foreach_sockclnt_api_msg;
#undef _
  return 0;
}

VLIB_API_INIT_FUNCTION (sockclnt_vlib_api_init);

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