/* 
 *------------------------------------------------------------------
 * 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/mheap.h>
#include <vppinfra/heap.h>
#include <vppinfra/pool.h>
#include <vppinfra/format.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);
}

static svmdb_client_t *svmdb_map_internal (char *root_path, uword size)
{
    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(root_path);

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

    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... */

    /* Add a bogus client (pid=0) so the svm won't be deallocated */
    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);
}
svmdb_client_t *svmdb_map (void)
{
    return svmdb_map_internal (0, 0);
}

svmdb_client_t *svmdb_map_size (uword size)
{
    return svmdb_map_internal (0, size);
}

svmdb_client_t *svmdb_map_chroot (char *root_path)
{
    return svmdb_map_internal (root_path, 0);
}

svmdb_client_t *svmdb_map_chroot_size (char *root_path, uword size)
{
    return svmdb_map_internal (root_path, size);
}

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 *dummy_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,
                                   dummy_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);
        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];
    
    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)");
    }));
    region_unlock (client->db_rp);
}

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];

    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]);
    }));

    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);
        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);
}
