/*
 *------------------------------------------------------------------
 * persist.c - persistent data structure storage test / demo code
 *
 * Copyright (c) 2013 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>

typedef struct
{
  svmdb_client_t *c;
} persist_main_t;

persist_main_t persist_main;

typedef struct
{
  u8 *string1;
  u8 *string2;
} demo_struct2_t;

typedef struct
{
  demo_struct2_t *demo2;
  u8 *name;
} demo_struct1_t;

/*
 * Data structures in persistent shared memory, all the time
 */
clib_error_t *
persist_malloc (persist_main_t * pm)
{
  demo_struct2_t *demo2;
  demo_struct1_t *demo1;
  time_t starttime = time (0);
  char *datestring = ctime (&starttime);
  void *oldheap;

  /* Get back the root pointer */
  demo1 = svmdb_local_get_variable_reference
    (pm->c, SVMDB_NAMESPACE_VEC, "demo1_location");

  /* It doesnt exist create our data structures */
  if (demo1 == 0)
    {
      /* If you want MP / thread safety, lock the region... */
      pthread_mutex_lock (&pm->c->db_rp->mutex);

      /* Switch to the shared memory region heap */
      oldheap = svm_push_data_heap (pm->c->db_rp);

      /* Allocate the top-level structure as a single element vector */
      vec_validate (demo1, 0);

      /* Allocate the next-level structure as a plain old memory obj */
      demo2 = clib_mem_alloc (sizeof (*demo2));

      demo1->demo2 = demo2;
      demo1->name = format (0, "My name is Ishmael%c", 0);
      demo2->string1 = format (0, "Here is string1%c", 0);
      demo2->string2 = format (0, "Born at %s%c", datestring, 0);

      /* Back to the process-private heap */
      svm_pop_heap (oldheap);
      pthread_mutex_unlock (&pm->c->db_rp->mutex);

      /*
       * Set the root pointer. Note: this guy switches heaps, locks, etc.
       * We allocated demo1 as a vector to make this "just work..."
       */
      svmdb_local_set_vec_variable (pm->c, "demo1_location",
				    demo1, sizeof (demo1));

    }
  else
    {
      /* retrieve and print data from shared memory */
      demo2 = demo1->demo2;
      fformat (stdout, "name: %s\n", demo1->name);
      fformat (stdout, "demo2 location: %llx\n", demo2);
      fformat (stdout, "string1: %s\n", demo2->string1);
      fformat (stdout, "string2: %s\n", demo2->string2);
    }
  return 0;
}

void
unserialize_demo1 (serialize_main_t * sm, va_list * args)
{
  demo_struct1_t **result = va_arg (*args, demo_struct1_t **);
  demo_struct1_t *demo1;
  demo_struct2_t *demo2;

  /* Allocate data structures in process private memory */
  demo1 = clib_mem_alloc (sizeof (*demo1));
  demo2 = clib_mem_alloc (sizeof (*demo2));
  demo1->demo2 = demo2;

  /* retrieve data from shared memory checkpoint */
  unserialize_cstring (sm, (char **) &demo1->name);
  unserialize_cstring (sm, (char **) &demo2->string1);
  unserialize_cstring (sm, (char **) &demo2->string2);
  *result = demo1;
}

void
serialize_demo1 (serialize_main_t * sm, va_list * args)
{
  demo_struct1_t *demo1 = va_arg (*args, demo_struct1_t *);
  demo_struct2_t *demo2 = demo1->demo2;

  serialize_cstring (sm, (char *) demo1->name);
  serialize_cstring (sm, (char *) demo2->string1);
  serialize_cstring (sm, (char *) demo2->string2);
}

/* Serialize / unserialize variant */
clib_error_t *
persist_serialize (persist_main_t * pm)
{
  u8 *checkpoint;
  serialize_main_t sm;

  demo_struct2_t *demo2;
  demo_struct1_t *demo1;
  time_t starttime = time (0);
  char *datestring = ctime (&starttime);

  /* Get back the root pointer */
  checkpoint = svmdb_local_get_vec_variable (pm->c, "demo1_checkpoint",
					     sizeof (u8));

  /* It doesnt exist create our data structures */
  if (checkpoint == 0)
    {
      /* Allocate data structures in process-private memory */
      demo1 = clib_mem_alloc (sizeof (*demo2));
      vec_validate (demo1, 0);
      demo2 = clib_mem_alloc (sizeof (*demo2));

      demo1->demo2 = demo2;
      demo1->name = format (0, "My name is Ishmael%c", 0);
      demo2->string1 = format (0, "Here is string1%c", 0);
      demo2->string2 = format (0, "Born at %s%c", datestring, 0);

      /* Create checkpoint */
      serialize_open_vector (&sm, checkpoint);
      serialize (&sm, serialize_demo1, demo1);
      checkpoint = serialize_close_vector (&sm);

      /* Copy checkpoint into shared memory */
      svmdb_local_set_vec_variable (pm->c, "demo1_checkpoint",
				    checkpoint, sizeof (u8));
      /* Toss the process-private-memory original.. */
      vec_free (checkpoint);
    }
  else
    {
      /* Open the checkpoint */
      unserialize_open_data (&sm, checkpoint, vec_len (checkpoint));
      unserialize (&sm, unserialize_demo1, &demo1);

      /* Toss the process-private-memory checkpoint copy */
      vec_free (checkpoint);

      /* Off we go... */
      demo2 = demo1->demo2;
      fformat (stdout, "name: %s\n", demo1->name);
      fformat (stdout, "demo2 location: %llx\n", demo2);
      fformat (stdout, "string1: %s\n", demo2->string1);
      fformat (stdout, "string2: %s\n", demo2->string2);
    }
  return 0;
}


int
main (int argc, char **argv)
{
  unformat_input_t _input, *input = &_input;
  persist_main_t *pm = &persist_main;
  clib_error_t *error = 0;

  /* Make a 4mb database arena, chroot so it's truly private */
  pm->c = svmdb_map_chroot_size ("/ptest", 4 << 20);

  ASSERT (pm->c);

  unformat_init_command_line (input, argv);

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "malloc"))
	error = persist_malloc (pm);
      else if (unformat (input, "serialize"))
	error = persist_serialize (pm);
      else
	{
	  error = clib_error_return (0, "Unknown flavor '%U'",
				     format_unformat_error, input);
	  break;
	}
    }

  svmdb_unmap (pm->c);

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

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