/*
* Copyright (c) 2017-2019 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 <vnet/session/application.h>
#include <vnet/session/application_interface.h>
#include <vnet/session/session.h>
#include <vppinfra/tw_timer_2t_1w_2048sl.h>

typedef enum
{
  EVENT_WAKEUP = 1,
} http_process_event_t;

typedef struct
{
  u32 hs_index;
  u32 thread_index;
  u64 node_index;
} http_server_args;

typedef enum
{
  HTTP_STATE_CLOSED,
  HTTP_STATE_ESTABLISHED,
  HTTP_STATE_OK_SENT,
} http_session_state_t;
typedef struct
{
  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
#define _(type, name) type name;
  foreach_app_session_field
#undef _
  u32 thread_index;
  u8 *rx_buf;
  u32 vpp_session_index;
  u64 vpp_session_handle;
  u32 timer_handle;
} http_session_t;

typedef struct
{
  http_session_t **sessions;
  clib_rwlock_t sessions_lock;
  u32 **session_to_http_session;

  svm_msg_q_t **vpp_queue;

  uword *handler_by_get_request;

  u32 *free_http_cli_process_node_indices;

  /* Sever's event queue */
  svm_queue_t *vl_input_queue;

  /* API client handle */
  u32 my_client_index;

  u32 app_index;

  /* process node index for evnt scheduling */
  u32 node_index;

  tw_timer_wheel_2t_1w_2048sl_t tw;
  clib_spinlock_t tw_lock;

  u32 prealloc_fifos;
  u32 private_segment_size;
  u32 fifo_size;
  u8 *uri;
  u32 is_static;
  vlib_main_t *vlib_main;
} http_server_main_t;

http_server_main_t http_server_main;

static void
http_server_sessions_reader_lock (void)
{
  clib_rwlock_reader_lock (&http_server_main.sessions_lock);
}

static void
http_server_sessions_reader_unlock (void)
{
  clib_rwlock_reader_unlock (&http_server_main.sessions_lock);
}

static void
http_server_sessions_writer_lock (void)
{
  clib_rwlock_writer_lock (&http_server_main.sessions_lock);
}

static void
http_server_sessions_writer_unlock (void)
{
  clib_rwlock_writer_unlock (&http_server_main.sessions_lock);
}

static http_session_t *
http_server_session_alloc (u32 thread_index)
{
  http_server_main_t *hsm = &http_server_main;
  http_session_t *hs;
  pool_get (hsm->sessions[thread_index], hs);
  memset (hs, 0, sizeof (*hs));
  hs->session_index = hs - hsm->sessions[thread_index];
  hs->thread_index = thread_index;
  hs->timer_handle = ~0;
  return hs;
}

static http_session_t *
http_server_session_get (u32 thread_index, u32 hs_index)
{
  http_server_main_t *hsm = &http_server_main;
  if (pool_is_free_index (hsm->sessions[thread_index], hs_index))
    return 0;
  return pool_elt_at_index (hsm->sessions[thread_index], hs_index);
}

static void
http_server_session_free (http_session_t * hs)
{
  http_server_main_t *hsm = &http_server_main;
  pool_put (hsm->sessions[hs->thread_index], hs);
  if (CLIB_DEBUG)
    memset (hs, 0xfa, sizeof (*hs));
}

static void
http_server_session_lookup_add (u32 thread_index, u32 s_index, u32 hs_index)
{
  http_server_main_t *hsm = &http_server_main;
  vec_validate (hsm->session_to_http_session[thread_index], s_index);
  hsm->session_to_http_session[thread_index][s_index] = hs_index;
}

static void
http_server_session_lookup_del (u32 thread_index, u32 s_index)
{
  http_server_main_t *hsm = &http_server_main;
  hsm->session_to_http_session[thread_index][s_index] = ~0;
}

static http_session_t *
http_server_session_lookup (u32 thread_index, u32 s_index)
{
  http_server_main_t *hsm = &http_server_main;
  u32 hs_index;

  if (s_index < vec_len (hsm->session_to_http_session[thread_index]))
    {
      hs_index = hsm->session_to_http_session[thread_index][s_index];
      return http_server_session_get (thread_index, hs_index);
    }
  return 0;
}


static void
http_server_session_timer_start (http_session_t * hs)
{
  u32 hs_handle;
  hs_handle = hs->thread_index << 24 | hs->session_index;
  clib_spinlock_lock (&http_server_main.tw_lock);
  hs->timer_handle = tw_timer_start_2t_1w_2048sl (&http_server_main.tw,
						  hs_handle, 0, 60);
  clib_spinlock_unlock (&http_server_main.tw_lock);
}

static void
http_server_session_timer_stop (http_session_t * hs)
{
  if (hs->timer_handle == ~0)
    return;
  clib_spinlock_lock (&http_server_main.tw_lock);
  tw_timer_stop_2t_1w_2048sl (&http_server_main.tw, hs->timer_handle);
  clib_spinlock_unlock (&http_server_main.tw_lock);
}

static void
http_server_session_cleanup (http_session_t * hs)
{
  if (!hs)
    return;
  http_server_session_lookup_del (hs->thread_index, hs->vpp_session_index);
  vec_free (hs->rx_buf);
  http_server_session_timer_stop (hs);
  http_server_session_free (hs);
}

static void
http_server_session_disconnect (http_session_t * hs)
{
  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
  a->handle = hs->vpp_session_handle;
  a->app_index = http_server_main.app_index;
  vnet_disconnect_session (a);
}

static void
http_process_free (http_server_args * args)
{
  vlib_node_runtime_t *rt;
  vlib_main_t *vm = &vlib_global_main;
  http_server_main_t *hsm = &http_server_main;
  vlib_node_t *n;
  u32 node_index;
  http_server_args **save_args;

  node_index = args->node_index;
  ASSERT (node_index != 0);

  n = vlib_get_node (vm, node_index);
  rt = vlib_node_get_runtime (vm, n->index);
  save_args = vlib_node_get_runtime_data (vm, n->index);

  /* Reset process session pointer */
  clib_mem_free (*save_args);
  *save_args = 0;

  /* Turn off the process node */
  vlib_node_set_state (vm, rt->node_index, VLIB_NODE_STATE_DISABLED);

  /* add node index to the freelist */
  vec_add1 (hsm->free_http_cli_process_node_indices, node_index);
}

/* *INDENT-OFF* */
static const char *http_ok =
    "HTTP/1.1 200 OK\r\n";

static const char *http_response =
    "Content-Type: text/html\r\n"
    "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
    "Connection: close \r\n"
    "Pragma: no-cache\r\n"
    "Content-Length: %d\r\n\r\n%s";

static const char *http_error_template =
    "HTTP/1.1 %s\r\n"
    "Content-Type: text/html\r\n"
    "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
    "Connection: close\r\n"
    "Pragma: no-cache\r\n"
    "Content-Length: 0\r\n\r\n";

/* Header, including incantation to suppress favicon.ico requests */
static const char *html_header_template =
    "<html><head><title>%v</title></head>"
    "<link rel=\"icon\" href=\"data:,\">"
    "<body><pre>";

static const char *html_footer =
    "</pre></body></html>\r\n";

static const char *html_header_static =
    "<html><head><title>static reply</title></head>"
    "<link rel=\"icon\" href=\"data:,\">"
    "<body><pre>hello</pre></body></html>\r\n";
/* *INDENT-ON* */

static u8 *static_http;
static u8 *static_ok;

static void
http_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
{
  u8 **output_vecp = (u8 **) arg;
  u8 *output_vec;
  u32 offset;

  output_vec = *output_vecp;

  offset = vec_len (output_vec);
  vec_validate (output_vec, offset + buffer_bytes - 1);
  clib_memcpy_fast (output_vec + offset, buffer, buffer_bytes);

  *output_vecp = output_vec;
}

void
send_data (http_session_t * hs, u8 * data)
{
  http_server_main_t *hsm = &http_server_main;
  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
  vlib_main_t *vm = vlib_get_main ();
  f64 last_sent_timer = vlib_time_now (vm);
  u32 offset, bytes_to_send;
  f64 delay = 10e-3;

  bytes_to_send = vec_len (data);
  offset = 0;

  while (bytes_to_send > 0)
    {
      int actual_transfer;

      actual_transfer = svm_fifo_enqueue_nowait
	(hs->tx_fifo, bytes_to_send, data + offset);

      /* Made any progress? */
      if (actual_transfer <= 0)
	{
	  http_server_sessions_reader_unlock ();
	  vlib_process_suspend (vm, delay);
	  http_server_sessions_reader_lock ();

	  /* 10s deadman timer */
	  if (vlib_time_now (vm) > last_sent_timer + 10.0)
	    {
	      a->handle = hs->vpp_session_handle;
	      a->app_index = hsm->app_index;
	      vnet_disconnect_session (a);
	      break;
	    }
	  /* Exponential backoff, within reason */
	  if (delay < 1.0)
	    delay = delay * 2.0;
	}
      else
	{
	  last_sent_timer = vlib_time_now (vm);
	  offset += actual_transfer;
	  bytes_to_send -= actual_transfer;

	  if (svm_fifo_set_event (hs->tx_fifo))
	    session_send_io_evt_to_thread (hs->tx_fifo,
					   SESSION_IO_EVT_TX_FLUSH);
	  delay = 10e-3;
	}
    }
}

static void
send_error (http_session_t * hs, char *str)
{
  u8 *data;

  data = format (0, http_error_template, str);
  send_data (hs, data);
  vec_free (data);
}

static uword
http_cli_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
		  vlib_frame_t * f)
{
  u8 *request = 0, *reply = 0, *http = 0, *html = 0;
  http_server_main_t *hsm = &http_server_main;
  http_server_args **save_args;
  http_server_args *args;
  unformat_input_t input;
  http_session_t *hs;
  int i;

  save_args = vlib_node_get_runtime_data (hsm->vlib_main, rt->node_index);
  args = *save_args;

  http_server_sessions_reader_lock ();

  hs = http_server_session_get (args->thread_index, args->hs_index);
  ASSERT (hs);

  request = hs->rx_buf;
  if (vec_len (request) < 7)
    {
      send_error (hs, "400 Bad Request");
      goto out;
    }

  for (i = 0; i < vec_len (request) - 4; i++)
    {
      if (request[i] == 'G' &&
	  request[i + 1] == 'E' &&
	  request[i + 2] == 'T' && request[i + 3] == ' ')
	goto found;
    }
bad_request:
  send_error (hs, "400 Bad Request");
  goto out;

found:
  /* Lose "GET " */
  vec_delete (request, i + 5, 0);

  /* Replace slashes with spaces, stop at the end of the path */
  i = 0;
  while (1)
    {
      if (request[i] == '/')
	request[i] = ' ';
      else if (request[i] == ' ')
	{
	  /* vlib_cli_input is vector-based, no need for a NULL */
	  _vec_len (request) = i;
	  break;
	}
      i++;
      /* Should never happen */
      if (i == vec_len (request))
	goto bad_request;
    }

  /* Generate the html header */
  html = format (0, html_header_template, request /* title */ );

  /* Run the command */
  unformat_init_vector (&input, vec_dup (request));
  vlib_cli_input (vm, &input, http_cli_output, (uword) & reply);
  unformat_free (&input);
  request = 0;

  /* Generate the html page */
  html = format (html, "%v", reply);
  html = format (html, html_footer);
  /* And the http reply */
  http = format (0, http_ok, vec_len (http_ok));
  http = format (http, http_response, vec_len (html), html);

  /* Send it */
  send_data (hs, http);

out:
  /* Cleanup */
  http_server_sessions_reader_unlock ();
  vec_free (reply);
  vec_free (html);
  vec_free (http);

  http_process_free (args);
  return (0);
}

static void
alloc_http_process (http_server_args * args)
{
  char *name;
  vlib_node_t *n;
  http_server_main_t *hsm = &http_server_main;
  vlib_main_t *vm = hsm->vlib_main;
  uword l = vec_len (hsm->free_http_cli_process_node_indices);
  http_server_args **save_args;

  if (vec_len (hsm->free_http_cli_process_node_indices) > 0)
    {
      n = vlib_get_node (vm, hsm->free_http_cli_process_node_indices[l - 1]);
      vlib_node_set_state (vm, n->index, VLIB_NODE_STATE_POLLING);
      _vec_len (hsm->free_http_cli_process_node_indices) = l - 1;
    }
  else
    {
      static vlib_node_registration_t r = {
	.function = http_cli_process,
	.type = VLIB_NODE_TYPE_PROCESS,
	.process_log2_n_stack_bytes = 16,
	.runtime_data_bytes = sizeof (void *),
      };

      name = (char *) format (0, "http-cli-%d", l);
      r.name = name;
      vlib_register_node (vm, &r);
      vec_free (name);

      n = vlib_get_node (vm, r.index);
    }

  /* Save the node index in the args. It won't be zero. */
  args->node_index = n->index;

  /* Save the args (pointer) in the node runtime */
  save_args = vlib_node_get_runtime_data (vm, n->index);
  *save_args = clib_mem_alloc (sizeof (*args));
  clib_memcpy_fast (*save_args, args, sizeof (*args));

  vlib_start_process (vm, n->runtime_index);
}

static void
alloc_http_process_callback (void *cb_args)
{
  alloc_http_process ((http_server_args *) cb_args);
}

static int
session_rx_request (http_session_t * hs)
{
  u32 max_dequeue, cursize;
  int n_read;

  cursize = vec_len (hs->rx_buf);
  max_dequeue = svm_fifo_max_dequeue_cons (hs->rx_fifo);
  if (PREDICT_FALSE (max_dequeue == 0))
    return -1;

  vec_validate (hs->rx_buf, cursize + max_dequeue - 1);
  n_read = app_recv_stream_raw (hs->rx_fifo, hs->rx_buf + cursize,
				max_dequeue, 0, 0 /* peek */ );
  ASSERT (n_read == max_dequeue);
  if (svm_fifo_is_empty_cons (hs->rx_fifo))
    svm_fifo_unset_event (hs->rx_fifo);

  _vec_len (hs->rx_buf) = cursize + n_read;
  return 0;
}

static int
http_server_rx_callback (session_t * s)
{
  http_server_args args;
  http_session_t *hs;
  int rv;

  http_server_sessions_reader_lock ();

  hs = http_server_session_lookup (s->thread_index, s->session_index);
  if (!hs || hs->session_state != HTTP_STATE_ESTABLISHED)
    return -1;

  rv = session_rx_request (hs);
  if (rv)
    return rv;

  /* send the command to a new/recycled vlib process */
  args.hs_index = hs->session_index;
  args.thread_index = hs->thread_index;

  http_server_sessions_reader_unlock ();

  /* Send RPC request to main thread */
  if (vlib_get_thread_index () != 0)
    vlib_rpc_call_main_thread (alloc_http_process_callback, (u8 *) & args,
			       sizeof (args));
  else
    alloc_http_process (&args);
  return 0;
}

static int
http_server_rx_callback_static (session_t * s)
{
  http_session_t *hs;
  u32 request_len;
  u8 *request = 0;
  int i, rv;

  hs = http_server_session_lookup (s->thread_index, s->session_index);
  if (!hs || hs->session_state == HTTP_STATE_CLOSED)
    return 0;

  /* ok 200 was sent */
  if (hs->session_state == HTTP_STATE_OK_SENT)
    goto send_data;

  rv = session_rx_request (hs);
  if (rv)
    goto wait_for_data;

  request = hs->rx_buf;
  request_len = vec_len (request);
  if (vec_len (request) < 7)
    {
      send_error (hs, "400 Bad Request");
      goto close_session;
    }

  for (i = 0; i < request_len - 4; i++)
    {
      if (request[i] == 'G' &&
	  request[i + 1] == 'E' &&
	  request[i + 2] == 'T' && request[i + 3] == ' ')
	goto find_end;
    }
  send_error (hs, "400 Bad Request");
  goto close_session;

find_end:

  /* check for the end sequence: /r/n/r/n */
  if (request[request_len - 1] != 0xa || request[request_len - 3] != 0xa
      || request[request_len - 2] != 0xd || request[request_len - 4] != 0xd)
    goto wait_for_data;

  /* send 200 OK first */
  send_data (hs, static_ok);
  hs->session_state = HTTP_STATE_OK_SENT;
  goto postpone;

send_data:
  send_data (hs, static_http);

close_session:
  http_server_session_disconnect (hs);
  http_server_session_cleanup (hs);
  return 0;

postpone:
  (void) svm_fifo_set_event (hs->rx_fifo);
  session_send_io_evt_to_thread (hs->rx_fifo, SESSION_IO_EVT_BUILTIN_RX);
  return 0;

wait_for_data:
  return 0;
}

static int
http_server_session_accept_callback (session_t * s)
{
  http_server_main_t *hsm = &http_server_main;
  http_session_t *hs;

  hsm->vpp_queue[s->thread_index] =
    session_main_get_vpp_event_queue (s->thread_index);

  if (!hsm->is_static)
    http_server_sessions_writer_lock ();

  hs = http_server_session_alloc (s->thread_index);
  http_server_session_lookup_add (s->thread_index, s->session_index,
				  hs->session_index);
  hs->rx_fifo = s->rx_fifo;
  hs->tx_fifo = s->tx_fifo;
  hs->vpp_session_index = s->session_index;
  hs->vpp_session_handle = session_handle (s);
  hs->session_state = HTTP_STATE_ESTABLISHED;
  http_server_session_timer_start (hs);

  if (!hsm->is_static)
    http_server_sessions_writer_unlock ();

  s->session_state = SESSION_STATE_READY;
  return 0;
}

static void
http_server_session_disconnect_callback (session_t * s)
{
  http_server_main_t *hsm = &http_server_main;
  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
  http_session_t *hs;

  if (!hsm->is_static)
    http_server_sessions_writer_lock ();

  hs = http_server_session_lookup (s->thread_index, s->session_index);
  http_server_session_cleanup (hs);

  if (!hsm->is_static)
    http_server_sessions_writer_unlock ();

  a->handle = session_handle (s);
  a->app_index = hsm->app_index;
  vnet_disconnect_session (a);
}

static void
http_server_session_reset_callback (session_t * s)
{
  http_server_main_t *hsm = &http_server_main;
  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
  http_session_t *hs;

  if (!hsm->is_static)
    http_server_sessions_writer_lock ();

  hs = http_server_session_lookup (s->thread_index, s->session_index);
  http_server_session_cleanup (hs);

  if (!hsm->is_static)
    http_server_sessions_writer_unlock ();

  a->handle = session_handle (s);
  a->app_index = hsm->app_index;
  vnet_disconnect_session (a);
}

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

static int
http_server_add_segment_callback (u32 client_index, u64 segment_handle)
{
  clib_warning ("called...");
  return -1;
}

static session_cb_vft_t http_server_session_cb_vft = {
  .session_accept_callback = http_server_session_accept_callback,
  .session_disconnect_callback = http_server_session_disconnect_callback,
  .session_connected_callback = http_server_session_connected_callback,
  .add_segment_callback = http_server_add_segment_callback,
  .builtin_app_rx_callback = http_server_rx_callback,
  .session_reset_callback = http_server_session_reset_callback
};

static int
http_server_attach ()
{
  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
  http_server_main_t *hsm = &http_server_main;
  u64 options[APP_OPTIONS_N_OPTIONS];
  vnet_app_attach_args_t _a, *a = &_a;
  u32 segment_size = 128 << 20;

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

  if (hsm->private_segment_size)
    segment_size = hsm->private_segment_size;

  a->api_client_index = ~0;
  a->name = format (0, "test_http_server");
  a->session_cb_vft = &http_server_session_cb_vft;
  a->options = options;
  a->options[APP_OPTIONS_SEGMENT_SIZE] = segment_size;
  a->options[APP_OPTIONS_RX_FIFO_SIZE] =
    hsm->fifo_size ? hsm->fifo_size : 8 << 10;
  a->options[APP_OPTIONS_TX_FIFO_SIZE] =
    hsm->fifo_size ? hsm->fifo_size : 32 << 10;
  a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
  a->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = hsm->prealloc_fifos;

  if (vnet_application_attach (a))
    {
      vec_free (a->name);
      clib_warning ("failed to attach server");
      return -1;
    }
  vec_free (a->name);
  hsm->app_index = a->app_index;

  clib_memset (a_cert, 0, sizeof (*a_cert));
  a_cert->app_index = a->app_index;
  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
  clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len);
  vnet_app_add_tls_cert (a_cert);

  clib_memset (a_key, 0, sizeof (*a_key));
  a_key->app_index = a->app_index;
  vec_validate (a_key->key, test_srv_key_rsa_len);
  clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len);
  vnet_app_add_tls_key (a_key);

  return 0;
}

static int
http_server_listen ()
{
  http_server_main_t *hsm = &http_server_main;
  vnet_listen_args_t _a, *a = &_a;
  clib_memset (a, 0, sizeof (*a));
  a->app_index = hsm->app_index;
  a->uri = "tcp://0.0.0.0/80";
  if (hsm->uri)
    a->uri = (char *) hsm->uri;
  return vnet_bind_uri (a);
}

static void
http_server_session_cleanup_cb (void *hs_handlep)
{
  http_session_t *hs;
  uword hs_handle;
  hs_handle = pointer_to_uword (hs_handlep);
  hs = http_server_session_get (hs_handle >> 24, hs_handle & 0x00FFFFFF);
  if (!hs)
    return;
  hs->timer_handle = ~0;
  http_server_session_disconnect (hs);
  http_server_session_cleanup (hs);
}

static void
http_expired_timers_dispatch (u32 * expired_timers)
{
  u32 hs_handle;
  int i;

  for (i = 0; i < vec_len (expired_timers); i++)
    {
      /* Get session handle. The first bit is the timer id */
      hs_handle = expired_timers[i] & 0x7FFFFFFF;
      session_send_rpc_evt_to_thread (hs_handle >> 24,
				      http_server_session_cleanup_cb,
				      uword_to_pointer (hs_handle, void *));
    }
}

static uword
http_server_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
		     vlib_frame_t * f)
{
  http_server_main_t *hsm = &http_server_main;
  f64 now, timeout = 1.0;
  uword *event_data = 0;
  uword __clib_unused event_type;

  while (1)
    {
      vlib_process_wait_for_event_or_clock (vm, timeout);
      now = vlib_time_now (vm);
      event_type = vlib_process_get_events (vm, (uword **) & event_data);

      /* expire timers */
      clib_spinlock_lock (&http_server_main.tw_lock);
      tw_timer_expire_timers_2t_1w_2048sl (&hsm->tw, now);
      clib_spinlock_unlock (&http_server_main.tw_lock);

      vec_reset_length (event_data);
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (http_server_process_node) =
{
  .function = http_server_process,
  .type = VLIB_NODE_TYPE_PROCESS,
  .name = "http-server-process",
  .state = VLIB_NODE_STATE_DISABLED,
};
/* *INDENT-ON* */

static int
http_server_create (vlib_main_t * vm)
{
  vlib_thread_main_t *vtm = vlib_get_thread_main ();
  http_server_main_t *hsm = &http_server_main;
  u32 num_threads;
  vlib_node_t *n;

  num_threads = 1 /* main thread */  + vtm->n_threads;
  vec_validate (hsm->vpp_queue, num_threads - 1);
  vec_validate (hsm->sessions, num_threads - 1);
  vec_validate (hsm->session_to_http_session, num_threads - 1);

  clib_rwlock_init (&hsm->sessions_lock);
  clib_spinlock_init (&hsm->tw_lock);

  if (http_server_attach ())
    {
      clib_warning ("failed to attach server");
      return -1;
    }
  if (http_server_listen ())
    {
      clib_warning ("failed to start listening");
      return -1;
    }

  /* Init timer wheel and process */
  tw_timer_wheel_init_2t_1w_2048sl (&hsm->tw, http_expired_timers_dispatch,
				    1 /* timer interval */ , ~0);
  vlib_node_set_state (vm, http_server_process_node.index,
		       VLIB_NODE_STATE_POLLING);
  n = vlib_get_node (vm, http_server_process_node.index);
  vlib_start_process (vm, n->runtime_index);

  return 0;
}

static clib_error_t *
http_server_create_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  http_server_main_t *hsm = &http_server_main;
  unformat_input_t _line_input, *line_input = &_line_input;
  u64 seg_size;
  u8 *html;
  int rv;

  hsm->prealloc_fifos = 0;
  hsm->private_segment_size = 0;
  hsm->fifo_size = 0;
  hsm->is_static = 0;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    goto start_server;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "static"))
	hsm->is_static = 1;
      else
	if (unformat (line_input, "prealloc-fifos %d", &hsm->prealloc_fifos))
	;
      else if (unformat (line_input, "private-segment-size %U",
			 unformat_memory_size, &seg_size))
	{
	  if (seg_size >= 0x100000000ULL)
	    {
	      vlib_cli_output (vm, "private segment size %llu, too large",
			       seg_size);
	      return 0;
	    }
	  hsm->private_segment_size = seg_size;
	}
      else if (unformat (line_input, "fifo-size %d", &hsm->fifo_size))
	hsm->fifo_size <<= 10;
      else if (unformat (line_input, "uri %s", &hsm->uri))
	;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, line_input);
    }
  unformat_free (line_input);

start_server:

  if (hsm->my_client_index != (u32) ~ 0)
    return clib_error_return (0, "test http server is already running");

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

  if (hsm->is_static)
    {
      http_server_session_cb_vft.builtin_app_rx_callback =
	http_server_rx_callback_static;
      html = format (0, html_header_static);
      static_http = format (0, http_response, vec_len (html), html);
      static_ok = format (0, http_ok);
    }
  rv = http_server_create (vm);
  switch (rv)
    {
    case 0:
      break;
    default:
      return clib_error_return (0, "server_create returned %d", rv);
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (http_server_create_command, static) =
{
  .path = "test http server",
  .short_help = "test http server",
  .function = http_server_create_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
http_server_main_init (vlib_main_t * vm)
{
  http_server_main_t *hsm = &http_server_main;

  hsm->my_client_index = ~0;
  hsm->vlib_main = vm;
  return 0;
}

VLIB_INIT_FUNCTION (http_server_main_init);

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