/*
 *------------------------------------------------------------------
 * svmdb.c -- simple shared memory database
 *
 * Copyright (c) 2009 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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <vppinfra/clib.h>
#include <vppinfra/vec.h>
#include <vppinfra/hash.h>
#include <vppinfra/bitmap.h>
#include <vppinfra/fifo.h>
#include <vppinfra/time.h>
#include <vppinfra/heap.h>
#include <vppinfra/pool.h>
#include <vppinfra/format.h>
#include <vppinfra/serialize.h>

#include "svmdb.h"

static void local_set_variable_nolock (svmdb_client_t * client,
				       svmdb_namespace_t namespace,
				       u8 * var, u8 * val, u32 elsize);

always_inline void
region_lock (svm_region_t * rp, int tag)
{
  pthread_mutex_lock (&rp->mutex);
#ifdef MUTEX_DEBUG
  rp->mutex_owner_pid = getpid ();
  rp->mutex_owner_tag = tag;
#endif
}

always_inline void
region_unlock (svm_region_t * rp)
{
#ifdef MUTEX_DEBUG
  rp->mutex_owner_pid = 0;
  rp->mutex_owner_tag = 0;
#endif
  pthread_mutex_unlock (&rp->mutex);
}

svmdb_client_t *
svmdb_map (svmdb_map_args_t * dba)
{
  svmdb_client_t *client = 0;
  svm_map_region_args_t *a = 0;
  svm_region_t *db_rp;
  void *oldheap;
  svmdb_shm_hdr_t *hp = 0;

  vec_validate (client, 0);
  vec_validate (a, 0);

  svm_region_init_chroot_uid_gid (dba->root_path, dba->uid, dba->gid);

  a->root_path = dba->root_path;
  a->name = "/db";
  a->size = dba->size ? dba->size : SVMDB_DEFAULT_SIZE;
  a->flags = SVM_FLAGS_MHEAP;
  a->uid = dba->uid;
  a->gid = dba->gid;

  db_rp = client->db_rp = svm_region_find_or_create (a);

  ASSERT (db_rp);

  vec_free (a);

  region_lock (client->db_rp, 10);
  /* Has someone else set up the shared-memory variable table? */
  if (db_rp->user_ctx)
    {
      client->shm = (void *) db_rp->user_ctx;
      client->pid = getpid ();
      region_unlock (client->db_rp);
      ASSERT (client->shm->version == SVMDB_SHM_VERSION);
      return (client);
    }
  /* Nope, it's our problem... */

  if (CLIB_DEBUG > 2)
    {
      /* Add a bogus client (pid=0) so the svm won't be deallocated */
      clib_warning
	("[%d] adding fake client (pid=0) so '%s' won't be unlinked",
	 getpid (), db_rp->region_name);
      oldheap = svm_push_pvt_heap (db_rp);
      vec_add1 (client->db_rp->client_pids, 0);
      svm_pop_heap (oldheap);
    }
  oldheap = svm_push_data_heap (db_rp);

  vec_validate (hp, 0);
  hp->version = SVMDB_SHM_VERSION;
  hp->namespaces[SVMDB_NAMESPACE_STRING]
    = hash_create_string (0, sizeof (uword));
  hp->namespaces[SVMDB_NAMESPACE_VEC]
    = hash_create_string (0, sizeof (uword));

  db_rp->user_ctx = hp;
  client->shm = hp;

  svm_pop_heap (oldheap);
  region_unlock (client->db_rp);
  client->pid = getpid ();

  return (client);
}

void
svmdb_unmap (svmdb_client_t * client)
{
  ASSERT (client);

  if (!svm_get_root_rp ())
    return;

  svm_region_unmap ((void *) client->db_rp);
  svm_region_exit ();
  vec_free (client);
}

static void
notify_value (svmdb_value_t * v, svmdb_action_t a)
{
  int i;
  int rv;
  union sigval sv;
  u32 value;
  u32 *dead_registrations = 0;

  svmdb_notify_t *np;

  for (i = 0; i < vec_len (v->notifications); i++)
    {
      np = vec_elt_at_index (v->notifications, i);
      if (np->action == a)
	{
	  value = (np->action << 28) | (np->opaque);
	  sv.sival_ptr = (void *) (uword) value;
	  do
	    {
	      rv = 0;
	      if (sigqueue (np->pid, np->signum, sv) == 0)
		break;
	      rv = errno;
	    }
	  while (rv == EAGAIN);
	  if (rv == 0)
	    continue;
	  vec_add1 (dead_registrations, i);
	}
    }

  for (i = 0; i < vec_len (dead_registrations); i++)
    {
      np = vec_elt_at_index (v->notifications, dead_registrations[i]);
      clib_warning ("dead reg pid %d sig %d action %d opaque %x",
		    np->pid, np->signum, np->action, np->opaque);
      vec_delete (v->notifications, 1, dead_registrations[i]);
    }
  vec_free (dead_registrations);
}

int
svmdb_local_add_del_notification (svmdb_client_t * client,
				  svmdb_notification_args_t * a)
{
  uword *h;
  void *oldheap;
  hash_pair_t *hp;
  svmdb_shm_hdr_t *shm;
  u8 *placeholder_value = 0;
  svmdb_value_t *value;
  svmdb_notify_t *np;
  int i;
  int rv = 0;

  ASSERT (a->elsize);

  region_lock (client->db_rp, 18);
  shm = client->shm;
  oldheap = svm_push_data_heap (client->db_rp);

  h = shm->namespaces[a->nspace];

  hp = hash_get_pair_mem (h, a->var);
  if (hp == 0)
    {
      local_set_variable_nolock (client, a->nspace, (u8 *) a->var,
				 placeholder_value, a->elsize);
      /* might have moved */
      h = shm->namespaces[a->nspace];
      hp = hash_get_pair_mem (h, a->var);
      ASSERT (hp);
    }

  value = pool_elt_at_index (shm->values, hp->value[0]);

  for (i = 0; i < vec_len (value->notifications); i++)
    {
      np = vec_elt_at_index (value->notifications, i);
      if ((np->pid == client->pid)
	  && (np->signum == a->signum)
	  && (np->action == a->action) && (np->opaque == a->opaque))
	{
	  if (a->add_del == 0 /* delete */ )
	    {
	      vec_delete (value->notifications, 1, i);
	      goto out;
	    }
	  else
	    {			/* add */
	      clib_warning
		("%s: ignore dup reg pid %d signum %d action %d opaque %x",
		 a->var, client->pid, a->signum, a->action, a->opaque);
	      rv = -2;
	      goto out;
	    }
	}
    }
  if (a->add_del == 0)
    {
      rv = -3;
      goto out;
    }

  vec_add2 (value->notifications, np, 1);
  np->pid = client->pid;
  np->signum = a->signum;
  np->action = a->action;
  np->opaque = a->opaque;

out:
  svm_pop_heap (oldheap);
  region_unlock (client->db_rp);
  return rv;
}


static void
local_unset_variable_nolock (svmdb_client_t * client,
			     svmdb_namespace_t namespace, char *var)
{
  uword *h;
  svmdb_value_t *oldvalue;
  hash_pair_t *hp;

  h = client->shm->namespaces[namespace];
  hp = hash_get_pair_mem (h, var);
  if (hp)
    {
      oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]);
      if (vec_len (oldvalue->notifications))
	notify_value (oldvalue, SVMDB_ACTION_UNSET);
      /* zero length value means unset */
      _vec_len (oldvalue->value) = 0;
    }
  client->shm->namespaces[namespace] = h;
}

void
svmdb_local_unset_string_variable (svmdb_client_t * client, char *var)
{
  void *oldheap;

  region_lock (client->db_rp, 11);
  oldheap = svm_push_data_heap (client->db_rp);
  local_unset_variable_nolock (client, SVMDB_NAMESPACE_STRING, var);
  svm_pop_heap (oldheap);
  region_unlock (client->db_rp);
}

static void
local_set_variable_nolock (svmdb_client_t * client,
			   svmdb_namespace_t namespace,
			   u8 * var, u8 * val, u32 elsize)
{
  uword *h;
  hash_pair_t *hp;
  u8 *name;
  svmdb_shm_hdr_t *shm;

  shm = client->shm;
  h = shm->namespaces[namespace];
  hp = hash_get_pair_mem (h, var);
  if (hp)
    {
      svmdb_value_t *oldvalue;
      oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]);
      vec_alloc (oldvalue->value, vec_len (val) * elsize);
      clib_memcpy (oldvalue->value, val, vec_len (val) * elsize);
      _vec_len (oldvalue->value) = vec_len (val);
      notify_value (oldvalue, SVMDB_ACTION_SET);
    }
  else
    {
      svmdb_value_t *newvalue;
      pool_get (shm->values, newvalue);
      clib_memset (newvalue, 0, sizeof (*newvalue));
      newvalue->elsize = elsize;
      vec_alloc (newvalue->value, vec_len (val) * elsize);
      clib_memcpy (newvalue->value, val, vec_len (val) * elsize);
      _vec_len (newvalue->value) = vec_len (val);
      name = format (0, "%s%c", var, 0);
      hash_set_mem (h, name, newvalue - shm->values);
    }
  shm->namespaces[namespace] = h;
}

void
svmdb_local_set_string_variable (svmdb_client_t * client,
				 char *var, char *val)
{
  void *oldheap;

  region_lock (client->db_rp, 12);
  oldheap = svm_push_data_heap (client->db_rp);

  local_unset_variable_nolock (client, SVMDB_NAMESPACE_STRING, var);

  local_set_variable_nolock (client, SVMDB_NAMESPACE_STRING,
			     (u8 *) var, (u8 *) val, 1 /* elsize */ );
  svm_pop_heap (oldheap);
  region_unlock (client->db_rp);
}

static u8 *
local_get_variable_nolock (svmdb_client_t * client,
			   svmdb_namespace_t namespace, u8 * var)
{
  uword *h;
  uword *p;
  svmdb_shm_hdr_t *shm;
  svmdb_value_t *oldvalue;

  shm = client->shm;
  h = shm->namespaces[namespace];
  p = hash_get_mem (h, var);
  if (p)
    {
      oldvalue = pool_elt_at_index (shm->values, p[0]);
      notify_value (oldvalue, SVMDB_ACTION_GET);
      return (oldvalue->value);
    }
  return 0;
}

void *
svmdb_local_get_variable_reference (svmdb_client_t * client,
				    svmdb_namespace_t namespace, char *var)
{
  u8 *rv;

  region_lock (client->db_rp, 19);
  rv = local_get_variable_nolock (client, namespace, (u8 *) var);
  region_unlock (client->db_rp);
  return (void *) rv;
}

char *
svmdb_local_get_string_variable (svmdb_client_t * client, char *var)
{
  u8 *rv = 0;

  region_lock (client->db_rp, 13);
  rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_STRING, (u8 *) var);

  if (rv && vec_len (rv))
    {
      rv = format (0, "%s", rv);
      vec_add1 (rv, 0);
    }
  region_unlock (client->db_rp);
  return ((char *) rv);
}

void
svmdb_local_dump_strings (svmdb_client_t * client)
{
  uword *h;
  u8 *key;
  u32 value;
  svmdb_shm_hdr_t *shm = client->shm;

  region_lock (client->db_rp, 14);

  h = client->shm->namespaces[SVMDB_NAMESPACE_STRING];

  /* *INDENT-OFF* */
  hash_foreach_mem(key, value, h,
  ({
    svmdb_value_t *v = pool_elt_at_index (shm->values, value);

    fformat(stdout, "%s: %s\n", key,
            vec_len(v->value) ? v->value : (u8 *)"(nil)");
  }));
  /* *INDENT-ON* */
  region_unlock (client->db_rp);
}

int
svmdb_local_serialize_strings (svmdb_client_t * client, char *filename)
{
  uword *h;
  u8 *key;
  u32 value;
  svmdb_shm_hdr_t *shm = client->shm;
  serialize_main_t _sm, *sm = &_sm;
  clib_error_t *error = 0;
  u8 *sanitized_name = 0;
  int fd = 0;

  if (strstr (filename, "..") || index (filename, '/'))
    {
      error = clib_error_return (0, "Illegal characters in filename '%s'",
				 filename);
      goto out;
    }

  sanitized_name = format (0, "/tmp/%s%c", filename, 0);

  fd = creat ((char *) sanitized_name, 0644);

  if (fd < 0)
    {
      error = clib_error_return_unix (0, "Create '%s'", sanitized_name);
      goto out;
    }

  serialize_open_clib_file_descriptor (sm, fd);

  region_lock (client->db_rp, 20);

  h = client->shm->namespaces[SVMDB_NAMESPACE_STRING];

  serialize_likely_small_unsigned_integer (sm, hash_elts (h));

  /* *INDENT-OFF* */
  hash_foreach_mem(key, value, h,
  ({
    svmdb_value_t *v = pool_elt_at_index (shm->values, value);

    /* Omit names with nil values */
    if (vec_len(v->value))
      {
        serialize_cstring (sm, (char *)key);
        serialize_cstring (sm, (char *)v->value);
      }
  }));
  /* *INDENT-ON* */
  region_unlock (client->db_rp);

  serialize_close (sm);

out:
  if (fd > 0 && close (fd) < 0)
    error = clib_error_return_unix (0, "close fd %d", fd);

  if (error)
    {
      clib_error_report (error);
      return -1;
    }
  return 0;
}

int
svmdb_local_unserialize_strings (svmdb_client_t * client, char *filename)
{
  serialize_main_t _sm, *sm = &_sm;
  void *oldheap;
  clib_error_t *error = 0;
  u8 *key, *value;
  int fd = 0;
  u32 nelts;
  int i;

  fd = open (filename, O_RDONLY);

  if (fd < 0)
    {
      error = clib_error_return_unix (0, "Failed to open '%s'", filename);
      goto out;
    }

  unserialize_open_clib_file_descriptor (sm, fd);

  region_lock (client->db_rp, 21);
  oldheap = svm_push_data_heap (client->db_rp);

  nelts = unserialize_likely_small_unsigned_integer (sm);

  for (i = 0; i < nelts; i++)
    {
      unserialize_cstring (sm, (char **) &key);
      unserialize_cstring (sm, (char **) &value);
      local_set_variable_nolock (client, SVMDB_NAMESPACE_STRING,
				 key, value, 1 /* elsize */ );
      vec_free (key);
      vec_free (value);
    }
  svm_pop_heap (oldheap);
  region_unlock (client->db_rp);

  serialize_close (sm);

out:
  if (fd > 0 && close (fd) < 0)
    error = clib_error_return_unix (0, "close fd %d", fd);

  if (error)
    {
      clib_error_report (error);
      return -1;
    }
  return 0;
}

void
svmdb_local_unset_vec_variable (svmdb_client_t * client, char *var)
{
  void *oldheap;

  region_lock (client->db_rp, 15);
  oldheap = svm_push_data_heap (client->db_rp);
  local_unset_variable_nolock (client, SVMDB_NAMESPACE_VEC, var);
  svm_pop_heap (oldheap);
  region_unlock (client->db_rp);
}

void
svmdb_local_set_vec_variable (svmdb_client_t * client,
			      char *var, void *val_arg, u32 elsize)
{
  u8 *val = (u8 *) val_arg;
  void *oldheap;

  region_lock (client->db_rp, 16);
  oldheap = svm_push_data_heap (client->db_rp);

  local_unset_variable_nolock (client, SVMDB_NAMESPACE_VEC, var);
  local_set_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var,
			     val, elsize);

  svm_pop_heap (oldheap);
  region_unlock (client->db_rp);
}

void *
svmdb_local_get_vec_variable (svmdb_client_t * client, char *var, u32 elsize)
{
  u8 *rv = 0;
  u8 *copy = 0;

  region_lock (client->db_rp, 17);

  rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var);

  if (rv && vec_len (rv))
    {
      /* Make a copy in process-local memory */
      vec_alloc (copy, vec_len (rv) * elsize);
      clib_memcpy (copy, rv, vec_len (rv) * elsize);
      _vec_len (copy) = vec_len (rv);
      region_unlock (client->db_rp);
      return (copy);
    }
  region_unlock (client->db_rp);
  return (0);
}

void
svmdb_local_dump_vecs (svmdb_client_t * client)
{
  uword *h;
  u8 *key;
  u32 value;
  svmdb_shm_hdr_t *shm;

  region_lock (client->db_rp, 17);
  shm = client->shm;

  h = client->shm->namespaces[SVMDB_NAMESPACE_VEC];

  /* *INDENT-OFF* */
  hash_foreach_mem(key, value, h,
  ({
    svmdb_value_t *v = pool_elt_at_index (shm->values, value);
    (void) fformat(stdout, "%s:\n %U (%.2f)\n", key,
                   format_hex_bytes, v->value,
                   vec_len(v->value)*v->elsize, ((f64 *)(v->value))[0]);
  }));
  /* *INDENT-ON* */

  region_unlock (client->db_rp);
}

void *
svmdb_local_find_or_add_vec_variable (svmdb_client_t * client,
				      char *var, u32 nbytes)
{
  void *oldheap;
  u8 *rv = 0;

  region_lock (client->db_rp, 18);
  oldheap = svm_push_data_heap (client->db_rp);

  rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var);

  if (rv)
    {
      goto out;
    }
  else
    {
      uword *h;
      u8 *name;
      svmdb_shm_hdr_t *shm;
      svmdb_value_t *newvalue;

      shm = client->shm;
      h = shm->namespaces[SVMDB_NAMESPACE_VEC];

      pool_get (shm->values, newvalue);
      clib_memset (newvalue, 0, sizeof (*newvalue));
      newvalue->elsize = 1;
      vec_alloc (newvalue->value, nbytes);
      _vec_len (newvalue->value) = nbytes;
      name = format (0, "%s%c", var, 0);
      hash_set_mem (h, name, newvalue - shm->values);
      shm->namespaces[SVMDB_NAMESPACE_VEC] = h;
      rv = newvalue->value;
    }

out:
  svm_pop_heap (oldheap);
  region_unlock (client->db_rp);
  return (rv);
}

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