/*
 * 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 <vnet/session/segment_manager.h>
#include <vnet/session/session.h>
#include <vnet/session/application.h>

/**
 * Counter used to build segment names
 */
u32 segment_name_counter = 0;

/**
 * Pool of segment managers
 */
segment_manager_t *segment_managers = 0;

/*
 * Pool of segment manager properties
 */
static segment_manager_properties_t *segment_manager_properties_pool;

/**
 * Process private segment index
 */
u32 *private_segment_indices;

/**
 * Default fifo and segment size. TODO config.
 */
u32 default_fifo_size = 1 << 16;
u32 default_segment_size = 1 << 20;

segment_manager_properties_t *
segment_manager_properties_alloc (void)
{
  segment_manager_properties_t *props;
  pool_get (segment_manager_properties_pool, props);
  memset (props, 0, sizeof (*props));
  return props;
}

void
segment_manager_properties_free (segment_manager_properties_t * props)
{
  pool_put (segment_manager_properties_pool, props);
  memset (props, 0xFB, sizeof (*props));
}

segment_manager_properties_t *
segment_manager_properties_get (u32 smp_index)
{
  if (pool_is_free_index (segment_manager_properties_pool, smp_index))
    return 0;
  return pool_elt_at_index (segment_manager_properties_pool, smp_index);
}

u32
segment_manager_properties_index (segment_manager_properties_t * p)
{
  return p - segment_manager_properties_pool;
}

void
segment_manager_get_segment_info (u32 index, u8 ** name, u32 * size)
{
  svm_fifo_segment_private_t *s;
  s = svm_fifo_segment_get_segment (index);
  *name = s->h->segment_name;
  *size = s->ssvm.ssvm_size;
}

always_inline int
session_manager_add_segment_i (segment_manager_t * sm, u32 segment_size,
			       u8 * segment_name)
{
  svm_fifo_segment_create_args_t _ca, *ca = &_ca;
  segment_manager_properties_t *props;
  int rv;

  memset (ca, 0, sizeof (*ca));
  props = segment_manager_properties_get (sm->properties_index);
  if (!props->use_private_segment)
    {
      ca->segment_name = (char *) segment_name;
      ca->segment_size = segment_size;
      ca->rx_fifo_size = props->rx_fifo_size;
      ca->tx_fifo_size = props->tx_fifo_size;
      ca->preallocated_fifo_pairs = props->preallocated_fifo_pairs;

      rv = svm_fifo_segment_create (ca);
      if (rv)
	{
	  clib_warning ("svm_fifo_segment_create ('%s', %d) failed",
			ca->segment_name, ca->segment_size);
	  return VNET_API_ERROR_SVM_SEGMENT_CREATE_FAIL;
	}
    }
  else
    {
      u32 rx_fifo_size, tx_fifo_size, rx_rounded_data_size,
	tx_rounded_data_size;
      u32 approx_segment_count;
      u64 approx_total_size;

      ca->segment_name = "process-private-segment";
      ca->segment_size = ~0;
      ca->rx_fifo_size = props->rx_fifo_size;
      ca->tx_fifo_size = props->tx_fifo_size;
      ca->preallocated_fifo_pairs = props->preallocated_fifo_pairs;
      ca->private_segment_count = props->private_segment_count;
      ca->private_segment_size = props->private_segment_size;

      /* Default to a small private segment */
      if (ca->private_segment_size == 0)
	ca->private_segment_size = 128 << 20;

      /* Calculate space requirements */
      rx_rounded_data_size = (1 << (max_log2 (ca->rx_fifo_size)));
      tx_rounded_data_size = (1 << (max_log2 (ca->tx_fifo_size)));

      rx_fifo_size = sizeof (svm_fifo_t) + rx_rounded_data_size;
      tx_fifo_size = sizeof (svm_fifo_t) + tx_rounded_data_size;

      approx_total_size = (u64) ca->preallocated_fifo_pairs
	* (rx_fifo_size + tx_fifo_size);
      approx_segment_count =
	(approx_total_size +
	 (ca->private_segment_size - 1)) / (u64) ca->private_segment_size;

      /* The user asked us to figure it out... */
      if (ca->private_segment_count == 0)
	{
	  ca->private_segment_count = approx_segment_count;
	}
      /* Follow directions, but issue a warning */
      else if (approx_segment_count != ca->private_segment_count)
	{
	  clib_warning
	    ("Honoring segment count %u, but calculated count was %u",
	     ca->private_segment_count, approx_segment_count);
	}

      if (svm_fifo_segment_create_process_private (ca))
	clib_warning ("Failed to create process private segment");

      ASSERT (vec_len (ca->new_segment_indices));
    }
  vec_append (sm->segment_indices, ca->new_segment_indices);
  vec_free (ca->new_segment_indices);
  return 0;
}

int
session_manager_add_segment (segment_manager_t * sm)
{
  svm_fifo_segment_create_args_t _ca, *ca = &_ca;
  segment_manager_properties_t *props;
  u32 add_segment_size;
  u8 *segment_name;
  int rv;

  memset (ca, 0, sizeof (*ca));
  props = segment_manager_properties_get (sm->properties_index);
  segment_name = format (0, "%d-%d%c", getpid (), segment_name_counter++, 0);
  add_segment_size = props->add_segment_size ?
    props->add_segment_size : default_segment_size;

  rv = session_manager_add_segment_i (sm, add_segment_size, segment_name);
  vec_free (segment_name);
  return rv;
}

int
session_manager_add_first_segment (segment_manager_t * sm, u32 segment_size)
{
  u8 *segment_name;
  int rv;

  segment_name = format (0, "%d-%d%c", getpid (), segment_name_counter++, 0);
  rv = session_manager_add_segment_i (sm, segment_size, segment_name);
  vec_free (segment_name);
  return rv;
}

segment_manager_t *
segment_manager_new ()
{
  segment_manager_t *sm;
  pool_get (segment_managers, sm);
  memset (sm, 0, sizeof (*sm));
  return sm;
}

/**
 * Initializes segment manager based on options provided.
 * Returns error if svm segment allocation fails.
 */
int
segment_manager_init (segment_manager_t * sm, u32 props_index,
		      u32 first_seg_size)
{
  int rv;

  /* app allocates these */
  sm->properties_index = props_index;
  first_seg_size = first_seg_size > 0 ? first_seg_size : default_segment_size;
  rv = session_manager_add_first_segment (sm, first_seg_size);
  if (rv)
    {
      clib_warning ("Failed to allocate segment");
      return rv;
    }

  clib_spinlock_init (&sm->lockp);
  return 0;
}

u8
segment_manager_has_fifos (segment_manager_t * sm)
{
  svm_fifo_segment_private_t *segment;
  int i;

  for (i = 0; i < vec_len (sm->segment_indices); i++)
    {
      segment = svm_fifo_segment_get_segment (sm->segment_indices[i]);
      if (CLIB_DEBUG && i && !svm_fifo_segment_has_fifos (segment)
	  && !(segment->h->flags & FIFO_SEGMENT_F_IS_PREALLOCATED))
	clib_warning ("segment %d has no fifos!", sm->segment_indices[i]);
      if (svm_fifo_segment_has_fifos (segment))
	return 1;
    }
  return 0;
}

static u8
segment_manager_app_detached (segment_manager_t * sm)
{
  return (sm->app_index == SEGMENT_MANAGER_INVALID_APP_INDEX);
}

void
segment_manager_app_detach (segment_manager_t * sm)
{
  sm->app_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
}

static void
segment_manager_del_segment (segment_manager_t * sm, u32 segment_index)
{
  svm_fifo_segment_private_t *fifo_segment;
  u32 svm_segment_index;
  clib_spinlock_lock (&sm->lockp);
  svm_segment_index = sm->segment_indices[segment_index];
  fifo_segment = svm_fifo_segment_get_segment (svm_segment_index);
  if (!fifo_segment
      || ((fifo_segment->h->flags & FIFO_SEGMENT_F_IS_PREALLOCATED)
	  && !segment_manager_app_detached (sm)))
    {
      clib_spinlock_unlock (&sm->lockp);
      return;
    }
  svm_fifo_segment_delete (fifo_segment);
  vec_del1 (sm->segment_indices, segment_index);
  clib_spinlock_unlock (&sm->lockp);
}

/**
 * Initiate disconnects for all sessions 'owned' by a segment manager
 */
void
segment_manager_del_sessions (segment_manager_t * sm)
{
  int j;
  svm_fifo_segment_private_t *fifo_segment;
  svm_fifo_t *fifo;

  ASSERT (vec_len (sm->segment_indices));

  /* Across all fifo segments used by the server */
  for (j = 0; j < vec_len (sm->segment_indices); j++)
    {
      fifo_segment = svm_fifo_segment_get_segment (sm->segment_indices[j]);
      fifo = svm_fifo_segment_get_fifo_list (fifo_segment);

      /*
       * Remove any residual sessions from the session lookup table
       * Don't bother deleting the individual fifos, we're going to
       * throw away the fifo segment in a minute.
       */
      while (fifo)
	{
	  u32 session_index, thread_index;
	  stream_session_t *session;

	  session_index = fifo->master_session_index;
	  thread_index = fifo->master_thread_index;
	  session = session_get (session_index, thread_index);

	  /* Instead of directly removing the session call disconnect */
	  if (session->session_state != SESSION_STATE_CLOSED)
	    {
	      session->session_state = SESSION_STATE_CLOSED;
	      session_send_session_evt_to_thread (session_handle
						  (session),
						  FIFO_EVENT_DISCONNECT,
						  thread_index);
	    }
	  fifo = fifo->next;
	}

      /* Instead of removing the segment, test when cleaning up disconnected
       * sessions if the segment can be removed.
       */
    }
}

/**
 * Removes segment manager.
 *
 * Since the fifos allocated in the segment keep backpointers to the sessions
 * prior to removing the segment, we call session disconnect. This
 * subsequently propagates into transport.
 */
void
segment_manager_del (segment_manager_t * sm)
{
  int i;

  ASSERT (!segment_manager_has_fifos (sm)
	  && segment_manager_app_detached (sm));

  /* If we have empty preallocated segments that haven't been removed, remove
   * them now. Apart from that, the first segment in the first segment manager
   * is not removed when all fifos are removed. It can only be removed when
   * the manager is explicitly deleted/detached by the app. */
  for (i = vec_len (sm->segment_indices) - 1; i >= 0; i--)
    {
      if (CLIB_DEBUG)
	{
	  svm_fifo_segment_private_t *segment;
	  segment = svm_fifo_segment_get_segment (sm->segment_indices[i]);
	  ASSERT (!svm_fifo_segment_has_fifos (segment));
	}
      segment_manager_del_segment (sm, i);
    }
  clib_spinlock_free (&sm->lockp);
  if (CLIB_DEBUG)
    memset (sm, 0xfe, sizeof (*sm));
  pool_put (segment_managers, sm);
}

void
segment_manager_init_del (segment_manager_t * sm)
{
  segment_manager_app_detach (sm);
  if (segment_manager_has_fifos (sm))
    segment_manager_del_sessions (sm);
  else
    {
      ASSERT (!sm->first_is_protected || segment_manager_app_detached (sm));
      segment_manager_del (sm);
    }
}

int
segment_manager_alloc_session_fifos (segment_manager_t * sm,
				     svm_fifo_t ** server_rx_fifo,
				     svm_fifo_t ** server_tx_fifo,
				     u32 * fifo_segment_index)
{
  svm_fifo_segment_private_t *fifo_segment;
  segment_manager_properties_t *props;
  u32 fifo_size, sm_index;
  u8 added_a_segment = 0;
  int i;

  ASSERT (vec_len (sm->segment_indices));

  /* Make sure we don't have multiple threads trying to allocate segments
   * at the same time. */
  clib_spinlock_lock (&sm->lockp);

  /* Allocate svm fifos */
  props = segment_manager_properties_get (sm->properties_index);
again:
  for (i = 0; i < vec_len (sm->segment_indices); i++)
    {
      *fifo_segment_index = sm->segment_indices[i];
      fifo_segment = svm_fifo_segment_get_segment (*fifo_segment_index);

      fifo_size = props->rx_fifo_size;
      fifo_size = (fifo_size == 0) ? default_fifo_size : fifo_size;
      *server_rx_fifo =
	svm_fifo_segment_alloc_fifo (fifo_segment, fifo_size,
				     FIFO_SEGMENT_RX_FREELIST);

      fifo_size = props->tx_fifo_size;
      fifo_size = (fifo_size == 0) ? default_fifo_size : fifo_size;
      *server_tx_fifo =
	svm_fifo_segment_alloc_fifo (fifo_segment, fifo_size,
				     FIFO_SEGMENT_TX_FREELIST);

      if (*server_rx_fifo == 0)
	{
	  /* This would be very odd, but handle it... */
	  if (*server_tx_fifo != 0)
	    {
	      svm_fifo_segment_free_fifo (fifo_segment, *server_tx_fifo,
					  FIFO_SEGMENT_TX_FREELIST);
	      *server_tx_fifo = 0;
	    }
	  continue;
	}
      if (*server_tx_fifo == 0)
	{
	  if (*server_rx_fifo != 0)
	    {
	      svm_fifo_segment_free_fifo (fifo_segment, *server_rx_fifo,
					  FIFO_SEGMENT_RX_FREELIST);
	      *server_rx_fifo = 0;
	    }
	  continue;
	}
      break;
    }

  /* See if we're supposed to create another segment */
  if (*server_rx_fifo == 0)
    {
      if (props->add_segment && !props->use_private_segment)
	{
	  if (added_a_segment)
	    {
	      clib_warning ("added a segment, still can't allocate a fifo");
	      clib_spinlock_unlock (&sm->lockp);
	      return SESSION_ERROR_NEW_SEG_NO_SPACE;
	    }

	  if (session_manager_add_segment (sm))
	    {
	      clib_spinlock_unlock (&sm->lockp);
	      return VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
	    }

	  added_a_segment = 1;
	  goto again;
	}
      else
	{
	  clib_warning ("No space to allocate fifos!");
	  clib_spinlock_unlock (&sm->lockp);
	  return SESSION_ERROR_NO_SPACE;
	}
    }

  /* Backpointers to segment manager */
  sm_index = segment_manager_index (sm);
  (*server_tx_fifo)->segment_manager = sm_index;
  (*server_rx_fifo)->segment_manager = sm_index;

  clib_spinlock_unlock (&sm->lockp);

  if (added_a_segment)
    return application_add_segment_notify (sm->app_index,
					   *fifo_segment_index);

  return 0;
}

void
segment_manager_dealloc_fifos (u32 svm_segment_index, svm_fifo_t * rx_fifo,
			       svm_fifo_t * tx_fifo)
{
  segment_manager_t *sm;
  svm_fifo_segment_private_t *fifo_segment;
  u32 i, segment_index = ~0;
  u8 is_first;

  sm = segment_manager_get_if_valid (rx_fifo->segment_manager);

  /* It's possible to have no segment manager if the session was removed
   * as result of a detach. */
  if (!sm)
    return;

  fifo_segment = svm_fifo_segment_get_segment (svm_segment_index);
  svm_fifo_segment_free_fifo (fifo_segment, rx_fifo,
			      FIFO_SEGMENT_RX_FREELIST);
  svm_fifo_segment_free_fifo (fifo_segment, tx_fifo,
			      FIFO_SEGMENT_TX_FREELIST);

  /*
   * Try to remove svm segment if it has no fifos. This can be done only if
   * the segment is not the first in the segment manager or if it is first
   * and it is not protected. Moreover, if the segment is first and the app
   * has detached from the segment manager, remove the segment manager.
   */
  if (!svm_fifo_segment_has_fifos (fifo_segment))
    {
      is_first = sm->segment_indices[0] == svm_segment_index;

      /* Remove segment if it holds no fifos or first but not protected */
      if (!is_first || !sm->first_is_protected)
	{
	  /* Find the segment manager segment index */
	  for (i = 0; i < vec_len (sm->segment_indices); i++)
	    if (sm->segment_indices[i] == svm_segment_index)
	      {
		segment_index = i;
		break;
	      }
	  ASSERT (segment_index != (u32) ~ 0);
	  segment_manager_del_segment (sm, segment_index);
	}

      /* Remove segment manager if no sessions and detached from app */
      if (segment_manager_app_detached (sm)
	  && !segment_manager_has_fifos (sm))
	segment_manager_del (sm);
    }
}

/**
 * Allocates shm queue in the first segment
 */
unix_shared_memory_queue_t *
segment_manager_alloc_queue (segment_manager_t * sm, u32 queue_size)
{
  ssvm_shared_header_t *sh;
  svm_fifo_segment_private_t *segment;
  unix_shared_memory_queue_t *q;
  void *oldheap;

  ASSERT (sm->segment_indices != 0);

  segment = svm_fifo_segment_get_segment (sm->segment_indices[0]);
  sh = segment->ssvm.sh;

  oldheap = ssvm_push_heap (sh);
  q = unix_shared_memory_queue_init (queue_size,
				     sizeof (session_fifo_event_t),
				     0 /* consumer pid */ ,
				     0 /* signal when queue non-empty */ );
  ssvm_pop_heap (oldheap);
  return q;
}

/**
 * Frees shm queue allocated in the first segment
 */
void
segment_manager_dealloc_queue (segment_manager_t * sm,
			       unix_shared_memory_queue_t * q)
{
  ssvm_shared_header_t *sh;
  svm_fifo_segment_private_t *segment;
  void *oldheap;

  ASSERT (sm->segment_indices != 0);

  segment = svm_fifo_segment_get_segment (sm->segment_indices[0]);
  sh = segment->ssvm.sh;

  oldheap = ssvm_push_heap (sh);
  unix_shared_memory_queue_free (q);
  ssvm_pop_heap (oldheap);
}

static clib_error_t *
segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input,
			 vlib_cli_command_t * cmd)
{
  svm_fifo_segment_private_t *segments, *seg;
  segment_manager_t *sm;
  u8 show_segments = 0, verbose = 0, *name;
  uword address;
  u64 size;
  u32 active_fifos;
  u32 free_fifos;

  mheap_t *heap_header;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "segments"))
	show_segments = 1;
      else if (unformat (input, "verbose"))
	verbose = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }
  vlib_cli_output (vm, "%d segment managers allocated",
		   pool_elts (segment_managers));
  if (verbose && pool_elts (segment_managers))
    {
      vlib_cli_output (vm, "%-10s%=15s%=12s", "Index", "App Index",
		       "Segments");

      /* *INDENT-OFF* */
      pool_foreach (sm, segment_managers, ({
	vlib_cli_output (vm, "%-10d%=15d%=12d", segment_manager_index(sm),
			   sm->app_index, vec_len (sm->segment_indices));
      }));
      /* *INDENT-ON* */

    }
  if (show_segments)
    {
      segments = svm_fifo_segment_segments_pool ();
      vlib_cli_output (vm, "%d svm fifo segments allocated",
		       pool_elts (segments));
      vlib_cli_output (vm, "%-20s%=12s%=16s%=16s%=16s", "Name",
		       "HeapSize (M)", "ActiveFifos", "FreeFifos", "Address");

      /* *INDENT-OFF* */
      pool_foreach (seg, segments, ({
	if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE)
	  {
	    address = pointer_to_uword (seg->ssvm.sh->heap);
	    if (seg->h->flags & FIFO_SEGMENT_F_IS_MAIN_HEAP)
	      name = format (0, "main heap");
	    else
	      name = format (0, "private heap");
	    heap_header = mheap_header (seg->ssvm.sh->heap);
	    size = heap_header->max_size;
	  }
	else
	  {
	    address =  seg->ssvm.sh->ssvm_va;
	    size = seg->ssvm.ssvm_size;
	    name = seg->ssvm.sh->name;
	  }
	active_fifos = svm_fifo_segment_num_fifos (seg);
        free_fifos = svm_fifo_segment_num_free_fifos (seg, ~0 /* size */);
	vlib_cli_output (vm, "%-20v%=16llu%=16u%=16u%16llx",
                         name, size >> 20ULL, active_fifos, free_fifos,
			 address);
        if (verbose)
          vlib_cli_output (vm, "%U",
                           format_svm_fifo_segment, seg, verbose);
	if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE)
	  vec_free (name);
      }));
      /* *INDENT-ON* */

    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (segment_manager_show_command, static) =
{
  .path = "show segment-manager",
  .short_help = "show segment-manager [segments][verbose]",
  .function = segment_manager_show_fn,
};
/* *INDENT-ON* */

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