/*
 * Copyright (c) 2016 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.
 */

/** @file
    udp builtin server
*/

#include <vnet/udp/udp.h>
#include <vnet/session/session.h>
#include <vnet/session/application_interface.h>

/** per-worker built-in server copy buffers */
u8 **copy_buffers;
static int app_index = ~0;

static int
builtin_session_create_callback (stream_session_t * s)
{
  /* Simple version: declare session ready-to-go... */
  s->session_state = SESSION_STATE_READY;
  return 0;
}

static void
builtin_session_disconnect_callback (stream_session_t * s)
{
  stream_session_disconnect (s);
}

static void
builtin_session_reset_callback (stream_session_t * s)
{
  clib_warning ("Reset session %U", format_stream_session, s, 2);
  stream_session_cleanup (s);
}

static int
builtin_session_connected_callback (u32 app_index, u32 api_context,
				    stream_session_t * s, u8 is_fail)
{
  clib_warning ("called...");
  return -1;
}

static int
builtin_server_rx_callback (stream_session_t * s)
{
  svm_fifo_t *rx_fifo, *tx_fifo;
  u32 this_transfer, max_deq, max_enq;
  int actual_transfer;
  u8 *my_copy_buffer;
  session_fifo_event_t evt;
  unix_shared_memory_queue_t *q;

  my_copy_buffer = copy_buffers[s->thread_index];
  rx_fifo = s->server_rx_fifo;
  tx_fifo = s->server_tx_fifo;

  max_deq = svm_fifo_max_dequeue (rx_fifo);
  max_enq = svm_fifo_max_enqueue (tx_fifo);
  this_transfer = max_enq < max_deq ? max_enq : max_deq;

  vec_validate (my_copy_buffer, this_transfer - 1);
  _vec_len (my_copy_buffer) = this_transfer;

  actual_transfer = svm_fifo_dequeue_nowait (rx_fifo, this_transfer,
					     my_copy_buffer);
  ASSERT (actual_transfer == this_transfer);
  actual_transfer = svm_fifo_enqueue_nowait (tx_fifo, this_transfer,
					     my_copy_buffer);
  ASSERT (actual_transfer == this_transfer);

  copy_buffers[s->thread_index] = my_copy_buffer;

  if (svm_fifo_set_event (tx_fifo))
    {
      /* Fabricate TX event, send to ourselves */
      evt.fifo = tx_fifo;
      evt.event_type = FIFO_EVENT_APP_TX;
      q = session_manager_get_vpp_event_queue (s->thread_index);
      unix_shared_memory_queue_add (q, (u8 *) & evt,
				    0 /* do wait for mutex */ );
    }

  return 0;
}

/* *INDENT-OFF* */
static session_cb_vft_t builtin_server = {
    .session_accept_callback = builtin_session_create_callback,
    .session_connected_callback = builtin_session_connected_callback,
    .session_disconnect_callback = builtin_session_disconnect_callback,
    .builtin_server_rx_callback = builtin_server_rx_callback,
    .session_reset_callback = builtin_session_reset_callback
};
/* *INDENT-ON* */

static int
attach_builtin_uri_server ()
{
  vnet_app_attach_args_t _a, *a = &_a;
  u8 segment_name[128];
  u32 segment_name_length;
  u64 options[16];

  segment_name_length = ARRAY_LEN (segment_name);

  memset (a, 0, sizeof (*a));
  memset (options, 0, sizeof (options));

  a->api_client_index = ~0;
  a->segment_name = segment_name;
  a->segment_name_length = segment_name_length;
  a->session_cb_vft = &builtin_server;

  options[SESSION_OPTIONS_ACCEPT_COOKIE] = 0x12345678;
  options[SESSION_OPTIONS_SEGMENT_SIZE] = (2 << 30);	/*$$$$ config / arg */
  options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
  options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 1024;

  a->options = options;

  if (vnet_application_attach (a))
    return -1;

  app_index = a->app_index;
  return 0;
}

static int
bind_builtin_uri_server (u8 * uri)
{
  vnet_bind_args_t _a, *a = &_a;
  int rv;

  rv = attach_builtin_uri_server ();
  if (rv)
    return rv;

  memset (a, 0, sizeof (*a));
  a->uri = (char *) uri;
  a->app_index = app_index;

  rv = vnet_bind_uri (a);

  return rv;
}

static int
unbind_builtin_uri_server (u8 * uri)
{
  vnet_unbind_args_t _a, *a = &_a;

  a->app_index = app_index;
  a->uri = (char *) uri;

  return vnet_unbind_uri (a);
}

static clib_error_t *
builtin_server_init (vlib_main_t * vm)
{
  vlib_thread_main_t *vtm = vlib_get_thread_main ();
  u32 num_threads;

  num_threads = 1 /* main thread */  + vtm->n_threads;

  vec_validate (copy_buffers, num_threads - 1);
  return 0;
}

VLIB_INIT_FUNCTION (builtin_server_init);

static clib_error_t *
builtin_uri_bind_command_fn (vlib_main_t * vm,
			     unformat_input_t * input,
			     vlib_cli_command_t * cmd)
{
  u8 *uri = 0;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "uri %s", &uri))
	;
      else
	break;
    }

  if (uri == 0)
    return clib_error_return (0, "uri to bind not specified...");

  vnet_session_enable_disable (vm, 1 /* turn on UDP, etc. */ );

  rv = bind_builtin_uri_server (uri);

  vec_free (uri);

  switch (rv)
    {
    case 0:
      break;

    default:
      return clib_error_return (0, "bind_uri_server returned %d", rv);
      break;
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (builtin_uri_bind_command, static) =
{
  .path = "builtin uri bind",
  .short_help = "builtin uri bind",
  .function = builtin_uri_bind_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
builtin_uri_unbind_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  u8 *uri = 0;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "uri %s", &uri))
	;
      else
	break;
    }

  if (uri == 0)
    return clib_error_return (0, "uri to unbind not specified...");

  rv = unbind_builtin_uri_server (uri);

  vec_free (uri);

  switch (rv)
    {
    case 0:
      break;

    default:
      return clib_error_return (0, "unbind_uri_server returned %d", rv);
      break;
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (builtin_uri_unbind_command, static) =
{
  .path = "builtin uri unbind",
  .short_help = "builtin uri unbind",
  .function = builtin_uri_unbind_command_fn,
};
/* *INDENT-ON* */

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