/* SPDX-License-Identifier: Apache-2.0
 * Copyright(c) 2022 Cisco Systems, Inc.
 */

#include <vlib/vlib.h>
#include <vlib/stats/stats.h>

vlib_stats_main_t vlib_stats_main;

void
vlib_stats_segment_lock (void)
{
  vlib_main_t *vm = vlib_get_main ();
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();

  /* already locked by us */
  if (sm->shared_header->in_progress &&
      vm->thread_index == sm->locking_thread_index)
    goto done;

  ASSERT (sm->locking_thread_index == ~0);
  ASSERT (sm->shared_header->in_progress == 0);
  ASSERT (sm->n_locks == 0);

  clib_spinlock_lock (sm->stat_segment_lockp);

  sm->shared_header->in_progress = 1;
  sm->locking_thread_index = vm->thread_index;
done:
  sm->n_locks++;
}

void
vlib_stats_segment_unlock (void)
{
  vlib_main_t *vm = vlib_get_main ();
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();

  ASSERT (sm->shared_header->in_progress == 1);
  ASSERT (sm->locking_thread_index == vm->thread_index);
  ASSERT (sm->n_locks > 0);

  sm->n_locks--;

  if (sm->n_locks > 0)
    return;

  sm->shared_header->epoch++;
  __atomic_store_n (&sm->shared_header->in_progress, 0, __ATOMIC_RELEASE);
  sm->locking_thread_index = ~0;
  clib_spinlock_unlock (sm->stat_segment_lockp);
}

/*
 * Change heap to the stats shared memory segment
 */
void *
vlib_stats_set_heap ()
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();

  ASSERT (sm && sm->shared_header);
  return clib_mem_set_heap (sm->heap);
}

u32
vlib_stats_find_entry_index (char *fmt, ...)
{
  u8 *name;
  va_list va;

  va_start (va, fmt);
  name = va_format (0, fmt, &va);
  va_end (va);
  vec_add1 (name, 0);

  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  hash_pair_t *hp = hash_get_pair (sm->directory_vector_by_name, name);
  vec_free (name);
  return hp ? hp->value[0] : STAT_SEGMENT_INDEX_INVALID;
}

static void
hash_set_str_key_alloc (uword **h, const char *key, uword v)
{
  int size = strlen (key) + 1;
  void *copy = clib_mem_alloc (size);
  clib_memcpy_fast (copy, key, size);
  hash_set_mem (*h, copy, v);
}

static void
hash_unset_str_key_free (uword **h, const char *key)
{
  hash_pair_t *hp = hash_get_pair_mem (*h, key);
  if (hp)
    {
      void *_k = uword_to_pointer (hp->key, void *);
      hash_unset_mem (*h, _k);
      clib_mem_free (_k);
    }
}

u32
vlib_stats_create_counter (vlib_stats_entry_t *e)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  u32 index;

  if (sm->dir_vector_first_free_elt != CLIB_U32_MAX)
    {
      index = sm->dir_vector_first_free_elt;
      sm->dir_vector_first_free_elt = sm->directory_vector[index].index;
    }
  else
    {
      index = vec_len (sm->directory_vector);
      vec_validate (sm->directory_vector, index);
    }

  sm->directory_vector[index] = *e;

  hash_set_str_key_alloc (&sm->directory_vector_by_name, e->name, index);

  return index;
}

void
vlib_stats_remove_entry (u32 entry_index)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_entry_t *e = vlib_stats_get_entry (sm, entry_index);
  counter_t **c;
  vlib_counter_t **vc;
  void *oldheap;
  u32 i;

  if (entry_index >= vec_len (sm->directory_vector))
    return;

  vlib_stats_segment_lock ();

  switch (e->type)
    {
    case STAT_DIR_TYPE_NAME_VECTOR:
      for (i = 0; i < vec_len (e->string_vector); i++)
	vec_free (e->string_vector[i]);
      vec_free (e->string_vector);
      break;

    case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
      c = e->data;
      e->data = 0;
      oldheap = clib_mem_set_heap (sm->heap);
      for (i = 0; i < vec_len (c); i++)
	vec_free (c[i]);
      vec_free (c);
      clib_mem_set_heap (oldheap);
      break;

    case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
      vc = e->data;
      e->data = 0;
      oldheap = clib_mem_set_heap (sm->heap);
      for (i = 0; i < vec_len (vc); i++)
	vec_free (vc[i]);
      vec_free (vc);
      clib_mem_set_heap (oldheap);
      break;

    case STAT_DIR_TYPE_SCALAR_INDEX:
    case STAT_DIR_TYPE_SYMLINK:
      break;
    default:
      ASSERT (0);
    }

  vlib_stats_segment_unlock ();

  hash_unset_str_key_free (&sm->directory_vector_by_name, e->name);

  memset (e, 0, sizeof (*e));
  e->type = STAT_DIR_TYPE_EMPTY;

  e->value = sm->dir_vector_first_free_elt;
  sm->dir_vector_first_free_elt = entry_index;
}

static void
vlib_stats_set_entry_name (vlib_stats_entry_t *e, char *s)
{
  u32 i, len = VLIB_STATS_MAX_NAME_SZ - 1;

  for (i = 0; i < len; i++)
    {
      e->name[i] = s[i];
      if (s[i] == 0)
	return;
    }
  ASSERT (i < VLIB_STATS_MAX_NAME_SZ - 1);
  s[i] = 0;
}

static u32
vlib_stats_new_entry_internal (stat_directory_type_t t, u8 *name)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_shared_header_t *shared_header = sm->shared_header;
  vlib_stats_entry_t e = { .type = t };

  ASSERT (shared_header);

  u32 vector_index = vlib_stats_find_entry_index ("%v", name);
  if (vector_index != STAT_SEGMENT_INDEX_INVALID) /* Already registered */
    {
      vector_index = ~0;
      goto done;
    }

  vec_add1 (name, 0);
  vlib_stats_set_entry_name (&e, (char *) name);

  vlib_stats_segment_lock ();
  vector_index = vlib_stats_create_counter (&e);

  shared_header->directory_vector = sm->directory_vector;

  vlib_stats_segment_unlock ();

done:
  vec_free (name);
  return vector_index;
}

u32
vlib_stats_add_gauge (char *fmt, ...)
{
  va_list va;
  u8 *name;

  va_start (va, fmt);
  name = va_format (0, fmt, &va);
  va_end (va);
  return vlib_stats_new_entry_internal (STAT_DIR_TYPE_SCALAR_INDEX, name);
}

void
vlib_stats_set_gauge (u32 index, u64 value)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();

  ASSERT (index < vec_len (sm->directory_vector));
  sm->directory_vector[index].value = value;
}

u32
vlib_stats_add_timestamp (char *fmt, ...)
{
  va_list va;
  u8 *name;

  va_start (va, fmt);
  name = va_format (0, fmt, &va);
  va_end (va);
  return vlib_stats_new_entry_internal (STAT_DIR_TYPE_SCALAR_INDEX, name);
}

void
vlib_stats_set_timestamp (u32 entry_index, f64 value)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();

  ASSERT (entry_index < vec_len (sm->directory_vector));
  sm->directory_vector[entry_index].value = value;
}

vlib_stats_string_vector_t
vlib_stats_add_string_vector (char *fmt, ...)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  va_list va;
  vlib_stats_header_t *sh;
  vlib_stats_string_vector_t sv;
  u32 index;
  u8 *name;

  va_start (va, fmt);
  name = va_format (0, fmt, &va);
  va_end (va);

  index = vlib_stats_new_entry_internal (STAT_DIR_TYPE_NAME_VECTOR, name);
  if (index == CLIB_U32_MAX)
    return 0;

  sv = vec_new_generic (vlib_stats_string_vector_t, 0,
			sizeof (vlib_stats_header_t), 0, sm->heap);
  sh = vec_header (sv);
  sh->entry_index = index;
  sm->directory_vector[index].string_vector = sv;
  return sv;
}

void
vlib_stats_set_string_vector (vlib_stats_string_vector_t *svp,
			      u32 vector_index, char *fmt, ...)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_header_t *sh = vec_header (*svp);
  vlib_stats_entry_t *e = vlib_stats_get_entry (sm, sh->entry_index);
  va_list va;
  u8 *s;

  if (fmt[0] == 0)
    {
      if (vec_len (e->string_vector) <= vector_index)
	return;

      if (e->string_vector[vector_index] == 0)
	return;

      vlib_stats_segment_lock ();
      vec_free (e->string_vector[vector_index]);
      vlib_stats_segment_unlock ();
      return;
    }

  vlib_stats_segment_lock ();

  ASSERT (e->string_vector);

  vec_validate (e->string_vector, vector_index);
  svp[0] = e->string_vector;

  s = e->string_vector[vector_index];

  if (s == 0)
    s = vec_new_heap (u8 *, 0, sm->heap);

  vec_reset_length (s);

  va_start (va, fmt);
  s = va_format (s, fmt, &va);
  va_end (va);
  vec_add1 (s, 0);

  e->string_vector[vector_index] = s;

  vlib_stats_segment_unlock ();
}

void
vlib_stats_free_string_vector (vlib_stats_string_vector_t *sv)
{
  vlib_stats_header_t *sh = vec_header (*sv);
  vlib_stats_remove_entry (sh->entry_index);
}

u32
vlib_stats_add_counter_vector (char *fmt, ...)
{
  va_list va;
  u8 *name;

  va_start (va, fmt);
  name = va_format (0, fmt, &va);
  va_end (va);
  return vlib_stats_new_entry_internal (STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE,
					name);
}

u32
vlib_stats_add_counter_pair_vector (char *fmt, ...)
{
  va_list va;
  u8 *name;

  va_start (va, fmt);
  name = va_format (0, fmt, &va);
  va_end (va);
  return vlib_stats_new_entry_internal (STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED,
					name);
}

static int
vlib_stats_validate_will_expand_internal (u32 entry_index, va_list *va)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_entry_t *e = vlib_stats_get_entry (sm, entry_index);
  void *oldheap;
  int rv = 1;

  oldheap = clib_mem_set_heap (sm->heap);
  if (e->type == STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE)
    {
      u32 idx0 = va_arg (*va, u32);
      u32 idx1 = va_arg (*va, u32);
      u64 **data = e->data;

      if (idx0 >= vec_len (data))
	goto done;

      for (u32 i = 0; i <= idx0; i++)
	if (idx1 >= vec_max_len (data[i]))
	  goto done;
    }
  else if (e->type == STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED)
    {
      u32 idx0 = va_arg (*va, u32);
      u32 idx1 = va_arg (*va, u32);
      vlib_counter_t **data = e->data;

      va_end (*va);

      if (idx0 >= vec_len (data))
	goto done;

      for (u32 i = 0; i <= idx0; i++)
	if (idx1 >= vec_max_len (data[i]))
	  goto done;
    }
  else
    ASSERT (0);

  rv = 0;
done:
  clib_mem_set_heap (oldheap);
  return rv;
}

int
vlib_stats_validate_will_expand (u32 entry_index, ...)
{
  va_list va;
  int rv;

  va_start (va, entry_index);
  rv = vlib_stats_validate_will_expand_internal (entry_index, &va);
  va_end (va);
  return rv;
}

void
vlib_stats_validate (u32 entry_index, ...)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_entry_t *e = vlib_stats_get_entry (sm, entry_index);
  void *oldheap;
  va_list va;
  int will_expand;

  va_start (va, entry_index);
  will_expand = vlib_stats_validate_will_expand_internal (entry_index, &va);
  va_end (va);

  if (will_expand)
    vlib_stats_segment_lock ();

  oldheap = clib_mem_set_heap (sm->heap);

  va_start (va, entry_index);

  if (e->type == STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE)
    {
      u32 idx0 = va_arg (va, u32);
      u32 idx1 = va_arg (va, u32);
      u64 **data = e->data;

      vec_validate_aligned (data, idx0, CLIB_CACHE_LINE_BYTES);

      for (u32 i = 0; i <= idx0; i++)
	vec_validate_aligned (data[i], idx1, CLIB_CACHE_LINE_BYTES);
      e->data = data;
    }
  else if (e->type == STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED)
    {
      u32 idx0 = va_arg (va, u32);
      u32 idx1 = va_arg (va, u32);
      vlib_counter_t **data = e->data;

      vec_validate_aligned (data, idx0, CLIB_CACHE_LINE_BYTES);

      for (u32 i = 0; i <= idx0; i++)
	vec_validate_aligned (data[i], idx1, CLIB_CACHE_LINE_BYTES);
      e->data = data;
    }
  else
    ASSERT (0);

  va_end (va);

  clib_mem_set_heap (oldheap);

  if (will_expand)
    vlib_stats_segment_unlock ();
}

u32
vlib_stats_add_symlink (u32 entry_index, u32 vector_index, char *fmt, ...)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_shared_header_t *shared_header = sm->shared_header;
  vlib_stats_entry_t e;
  va_list va;
  u8 *name;

  ASSERT (shared_header);
  ASSERT (entry_index < vec_len (sm->directory_vector));

  va_start (va, fmt);
  name = va_format (0, fmt, &va);
  va_end (va);

  if (vlib_stats_find_entry_index ("%v", name) == STAT_SEGMENT_INDEX_INVALID)
    {
      vec_add1 (name, 0);
      vlib_stats_set_entry_name (&e, (char *) name);
      e.type = STAT_DIR_TYPE_SYMLINK;
      e.index1 = entry_index;
      e.index2 = vector_index;
      vector_index = vlib_stats_create_counter (&e);

      /* Warn clients to refresh any pointers they might be holding */
      shared_header->directory_vector = sm->directory_vector;
    }
  else
    vector_index = ~0;

  vec_free (name);
  return vector_index;
}

void
vlib_stats_rename_symlink (u64 entry_index, char *fmt, ...)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_entry_t *e = vlib_stats_get_entry (sm, entry_index);
  va_list va;
  u8 *new_name;

  hash_unset_str_key_free (&sm->directory_vector_by_name, e->name);

  va_start (va, fmt);
  new_name = va_format (0, fmt, &va);
  va_end (va);

  vec_add1 (new_name, 0);
  vlib_stats_set_entry_name (e, (char *) new_name);
  hash_set_str_key_alloc (&sm->directory_vector_by_name, e->name, entry_index);
  vec_free (new_name);
}

f64
vlib_stats_get_segment_update_rate (void)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  return sm->update_interval;
}

void
vlib_stats_register_collector_fn (vlib_stats_collector_reg_t *reg)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_collector_t *c;

  ASSERT (reg->entry_index != ~0);

  pool_get_zero (sm->collectors, c);
  c->fn = reg->collect_fn;
  c->entry_index = reg->entry_index;
  c->vector_index = reg->vector_index;
  c->private_data = reg->private_data;

  return;
}
