/*
 * Copyright (c) 2018 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 <vnet/vnet.h>
#include <vlibmemory/api.h>

#include <vnet/interface.h>
#include <vnet/api_errno.h>

#include <vnet/fib/fib_table.h>
#include <vnet/syslog/syslog.h>

#include <vnet/vnet_msg_enum.h>

#define vl_typedefs		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_typedefs

#define vl_endianfun		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_endianfun

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

#include <vlibapi/api_helper_macros.h>

#define foreach_vpe_api_msg             \
_(SYSLOG_SET_SENDER, syslog_set_sender) \
_(SYSLOG_GET_SENDER, syslog_get_sender) \
_(SYSLOG_SET_FILTER, syslog_set_filter) \
_(SYSLOG_GET_FILTER, syslog_get_filter)

static int
syslog_severity_decode (vl_api_syslog_severity_t v, syslog_severity_t * s)
{
  v = ntohl (v);
  int rv = 0;

  switch (v)
    {
    case SYSLOG_API_SEVERITY_EMERG:
      *s = SYSLOG_SEVERITY_EMERGENCY;
      break;
    case SYSLOG_API_SEVERITY_ALERT:
      *s = SYSLOG_SEVERITY_ALERT;
      break;
    case SYSLOG_API_SEVERITY_CRIT:
      *s = SYSLOG_SEVERITY_CRITICAL;
      break;
    case SYSLOG_API_SEVERITY_ERR:
      *s = SYSLOG_SEVERITY_ERROR;
      break;
    case SYSLOG_API_SEVERITY_WARN:
      *s = SYSLOG_SEVERITY_WARNING;
      break;
    case SYSLOG_API_SEVERITY_NOTICE:
      *s = SYSLOG_SEVERITY_NOTICE;
      break;
    case SYSLOG_API_SEVERITY_INFO:
      *s = SYSLOG_SEVERITY_INFORMATIONAL;
      break;
    case SYSLOG_API_SEVERITY_DBG:
      *s = SYSLOG_SEVERITY_DEBUG;
      break;
    default:
      rv = VNET_API_ERROR_INVALID_VALUE;
    }

  return rv;
}

static int
syslog_severity_encode (syslog_severity_t v, vl_api_syslog_severity_t * s)
{
  int rv = 0;
  switch (v)
    {
    case SYSLOG_SEVERITY_EMERGENCY:
      *s = SYSLOG_API_SEVERITY_EMERG;
      break;
    case SYSLOG_SEVERITY_ALERT:
      *s = SYSLOG_API_SEVERITY_ALERT;
      break;
    case SYSLOG_SEVERITY_CRITICAL:
      *s = SYSLOG_API_SEVERITY_CRIT;
      break;
    case SYSLOG_SEVERITY_ERROR:
      *s = SYSLOG_API_SEVERITY_ERR;
      break;
    case SYSLOG_SEVERITY_WARNING:
      *s = SYSLOG_API_SEVERITY_WARN;
      break;
    case SYSLOG_SEVERITY_NOTICE:
      *s = SYSLOG_API_SEVERITY_NOTICE;
      break;
    case SYSLOG_SEVERITY_INFORMATIONAL:
      *s = SYSLOG_API_SEVERITY_INFO;
      break;
    case SYSLOG_SEVERITY_DEBUG:
      *s = SYSLOG_API_SEVERITY_DBG;
      break;
    default:
      rv = VNET_API_ERROR_INVALID_VALUE;
    }

  *s = htonl (*s);
  return rv;
}

static void
vl_api_syslog_set_sender_t_handler (vl_api_syslog_set_sender_t * mp)
{
  vl_api_syslog_set_sender_reply_t *rmp;
  ip4_address_t collector, src;

  clib_memcpy (&collector, &mp->collector_address, sizeof (collector));
  clib_memcpy (&src, &mp->src_address, sizeof (src));

  int rv = set_syslog_sender (&collector, ntohs (mp->collector_port), &src,
			      ntohl (mp->vrf_id), ntohl (mp->max_msg_size));

  REPLY_MACRO (VL_API_SYSLOG_SET_SENDER_REPLY);
}

static void
vl_api_syslog_get_sender_t_handler (vl_api_syslog_get_sender_t * mp)
{
  int rv = 0;
  vl_api_syslog_get_sender_reply_t *rmp;
  syslog_main_t *sm = &syslog_main;
  u32 vrf_id;

  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_SYSLOG_GET_SENDER_REPLY,
  ({
    clib_memcpy (rmp->collector_address, &(sm->collector),
                 sizeof(ip4_address_t));
    clib_memcpy (rmp->src_address, &(sm->src_address),
                 sizeof(ip4_address_t));
    rmp->collector_port = htons (sm->collector_port);
    if (sm->fib_index == ~0)
      vrf_id = ~0;
    else
      vrf_id = htonl (fib_table_get_table_id (sm->fib_index, FIB_PROTOCOL_IP4));
    rmp->vrf_id = vrf_id;
    rmp->max_msg_size = htonl (sm->max_msg_size);
  }))
  /* *INDENT-ON* */
}

static void
vl_api_syslog_set_filter_t_handler (vl_api_syslog_set_filter_t * mp)
{
  vl_api_syslog_set_filter_reply_t *rmp;
  syslog_main_t *sm = &syslog_main;
  int rv = 0;
  syslog_severity_t s;

  rv = syslog_severity_decode (mp->severity, &s);
  if (rv)
    goto send_reply;

  sm->severity_filter = s;

send_reply:
  REPLY_MACRO (VL_API_SYSLOG_SET_FILTER_REPLY);
}

static void
vl_api_syslog_get_filter_t_handler (vl_api_syslog_get_filter_t * mp)
{
  int rv = 0;
  vl_api_syslog_get_filter_reply_t *rmp;
  syslog_main_t *sm = &syslog_main;

  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_SYSLOG_GET_FILTER_REPLY,
  ({
     rv = syslog_severity_encode (sm->severity_filter, &rmp->severity);
  }))
  /* *INDENT-ON* */
}

#define vl_msg_name_crc_list
#include <vnet/vnet_all_api_h.h>
#undef vl_msg_name_crc_list

static void
setup_message_id_table (api_main_t * am)
{
#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
  foreach_vl_msg_name_crc_syslog;
#undef _
}

static clib_error_t *
syslog_api_hookup (vlib_main_t * vm)
{
  api_main_t *am = &api_main;

#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_vpe_api_msg;
#undef _

  /*
   * Set up the (msg_name, crc, message-id) table
   */
  setup_message_id_table (am);

  return 0;
}

VLIB_API_INIT_FUNCTION (syslog_api_hookup);

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