/*
 * $Id$
 *
 */

#include <net-snmp/net-snmp-config.h>

#include <stdio.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_MALLOC_H
#include <malloc.h>
#endif
#include <sys/types.h>
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/types.h>
#include <net-snmp/library/snmp_api.h>
#include <net-snmp/library/container.h>
#include <net-snmp/library/tools.h>
#include <net-snmp/library/snmp_assert.h>

#include <net-snmp/library/container_iterator.h>

/** @typedef struct iterator_info_s iterator_info
 * Typedefs the iterator_info_s struct into iterator_info */

/** @struct iterator_info_s
    
* Holds iterator information containing functions which should be
called by the iterator_handler to loop over your data set and
sort it in a SNMP specific manner.

The iterator_info typedef can be used instead of directly
calling this struct if you would prefer.
*/
typedef struct iterator_info_s {
   /*
    * netsnmp_conatiner  must be first
    */
   netsnmp_container c;

   /*
    * iterator data
    */
   Netsnmp_Iterator_Loop_Key *get_first;
   Netsnmp_Iterator_Loop_Key *get_next;
   
   Netsnmp_Iterator_Loop_Data *get_data;

   Netsnmp_Iterator_Data *free_user_ctx;
   
   Netsnmp_Iterator_Ctx *init_loop_ctx;
   Netsnmp_Iterator_Ctx *cleanup_loop_ctx;
   Netsnmp_Iterator_Ctx_Dup *save_pos;
   
   Netsnmp_Iterator_Data * release_data;
   Netsnmp_Iterator_Data * insert_data;
   Netsnmp_Iterator_Data * remove_data;

   Netsnmp_Iterator_Op * get_size;
   
   int             sorted;
   
   /** This can be used by client handlers to store any
       information they need */
   void           *user_ctx;
} iterator_info;

/**********************************************************************
 *
 * iterator
 *
 **********************************************************************/
static void *
_iterator_get(iterator_info *ii, const void *key)
{
    int cmp, rc = SNMP_ERR_NOERROR;
    netsnmp_ref_void best = { NULL };
    netsnmp_ref_void tmp = { NULL };
    netsnmp_ref_void loop_ctx = { NULL };

    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_get"));
    
    if(ii->init_loop_ctx)
        ii->init_loop_ctx(ii->user_ctx, &loop_ctx);
    
    rc = ii->get_first(ii->user_ctx, &loop_ctx, &tmp);
    if(SNMP_ERR_NOERROR != rc) {
        if(SNMP_ENDOFMIBVIEW != rc)
            snmp_log(LOG_ERR, "bad rc %d from get_next\n", rc);
    }
    else {
        for( ;
             (NULL != tmp.val) && (SNMP_ERR_NOERROR == rc);
             rc = ii->get_next(ii->user_ctx, &loop_ctx, &tmp) ) {
            
            /*
             * if keys are equal, we are done.
             */
            cmp = ii->c.compare(tmp.val, key);
            if(0 == cmp) {
                best.val = tmp.val;
                if(ii->get_data)
                    ii->get_data(ii->user_ctx, &loop_ctx, &best);
            }
            
            /*
             * if data is sorted and if key is greater,
             * we are done (not found)
             */
            if((cmp > 0) && ii->sorted)
                break;
        } /* end for */
    }
    
    if(ii->cleanup_loop_ctx)
        ii->cleanup_loop_ctx(ii->user_ctx,&loop_ctx);

    return best.val;
}

/**
 *
 * NOTE: the returned data context can be reused, to save from
 *   having to allocate memory repeatedly. However, in this case,
 *   the get_data and get_pos functions must be implemented to
 *   return unique memory that will be saved for later comparisons.
 */
static void *
_iterator_get_next(iterator_info *ii, const void *key)
{
    int cmp, rc = SNMP_ERR_NOERROR;
    netsnmp_ref_void best_val = { NULL };
    netsnmp_ref_void best_ctx = { NULL };
    netsnmp_ref_void tmp = { NULL };
    netsnmp_ref_void loop_ctx = { NULL };

    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_get_next"));
    
    /*
     * initialize loop context
     */
    if(ii->init_loop_ctx)
        ii->init_loop_ctx(ii->user_ctx, &loop_ctx);
    
    /*
     * get first item
     */
    rc = ii->get_first(ii->user_ctx, &loop_ctx, &tmp);
    if(SNMP_ERR_NOERROR == rc) {
        /*
         * special case: if key is null, find the first item.
         * this is each if the container is sorted, since we're
         * already done!  Otherwise, get the next item for the
         * first comparison in the loop below.
         */
        if (NULL == key) {
            if(ii->get_data)
                ii->save_pos(ii->user_ctx, &loop_ctx, &best_ctx, 1);
            best_val.val = tmp.val;
            if(ii->sorted)
                tmp.val = NULL; /* so we skip for loop */
            else
                rc = ii->get_next(ii->user_ctx, &loop_ctx, &tmp);
        }
        /*
         * loop over remaining items
         */
        for( ;
             (NULL != tmp.val) && (rc == SNMP_ERR_NOERROR);
             rc = ii->get_next(ii->user_ctx, &loop_ctx, &tmp) ) {
            
            /*
             * if we have a key, this is a get-next, and we need to compare
             * the key to the tmp value to see if the tmp value is greater
             * than the key, but less than any previous match.
             *
             * if there is no key, this is a get-first, and we need to
             * compare the best value agains the tmp value to see if the
             * tmp value is lesser than the best match.
             */
            if(key) /* get next */
                cmp = ii->c.compare(tmp.val, key);
            else { /* get first */
                /*
                 * best value and tmp value should never be equal,
                 * otherwise we'd be comparing a pointer to itself.
                 * (see note on context reuse in comments above function.
                 */
                if(best_val.val == tmp.val) {
                    snmp_log(LOG_ERR,"illegal reuse of data context in "
                             "container_iterator\n");
                    rc = SNMP_ERR_GENERR;
                    break;
                }
                cmp = ii->c.compare(best_val.val, tmp.val);
            }
            if(cmp > 0) {
                /*
                 * if we don't have a key (get-first) or a current best match,
                 * then the comparison above is all we need to know that
                 * tmp is the best match. otherwise, compare against the
                 * current best match.
                 */
                if((NULL == key) || (NULL == best_val.val) ||
                   ((cmp=ii->c.compare(tmp.val, best_val.val)) < 0) ) {
                    DEBUGMSGT(("container_iterator:results"," best match\n"));
                    best_val.val = tmp.val;
                    if(ii->get_data)
                        ii->save_pos(ii->user_ctx, &loop_ctx, &best_ctx, 1);
                }
            }
            else if((cmp == 0) && ii->sorted && key) {
                /*
                 * if keys are equal and container is sorted, then we know
                 * the next key will be the one we want.
                 * NOTE: if no vars, treat as generr, since we
                 *    went past the end of the container when we know
                 *    the next item is the one we want. (IGN-A)
                 */
                rc = ii->get_next(ii->user_ctx, &loop_ctx, &tmp);
                if(SNMP_ERR_NOERROR == rc) {
                    best_val.val = tmp.val;
                    if(ii->get_data)
                        ii->save_pos(ii->user_ctx, &loop_ctx, &best_ctx, 1);
                }
                else if(SNMP_ENDOFMIBVIEW == rc)
                    rc = SNMPERR_GENERR; /* not found */
                break;
            }
            
        } /* end for */
    }

    /*
     * no vars is ok, except as noted above (IGN-A)
     */
    if(SNMP_ENDOFMIBVIEW == rc)
        rc = SNMP_ERR_NOERROR;
            
    /*
     * get data, iff necessary
     * clear return value iff errors
     */
    if(SNMP_ERR_NOERROR == rc) {
        if(ii->get_data && best_val.val) {
            rc = ii->get_data(ii->user_ctx, &best_ctx, &best_val);
            if(SNMP_ERR_NOERROR != rc) {
                snmp_log(LOG_ERR, "bad rc %d from get_data\n", rc);
                best_val.val = NULL;
            }
        }
    }
    else if(SNMP_ENDOFMIBVIEW != rc) {
        snmp_log(LOG_ERR, "bad rc %d from get_next\n", rc);
        best_val.val = NULL;
    }

    /*
     * if we have a saved loop ctx, clean it up
     */
    if((best_ctx.val != NULL) && (best_ctx.val != loop_ctx.val) &&
       (ii->cleanup_loop_ctx))
        ii->cleanup_loop_ctx(ii->user_ctx,&best_ctx);

    /*
     * clean up loop ctx
     */
    if(ii->cleanup_loop_ctx)
        ii->cleanup_loop_ctx(ii->user_ctx,&loop_ctx);

    DEBUGMSGT(("container_iterator:results"," returning %p\n", best_val.val));
    return best_val.val;
}

/**********************************************************************
 *
 * container
 *
 **********************************************************************/
static void
_iterator_free(iterator_info *ii)
{
    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_free"));
    
    if(NULL == ii)
        return;
    
    if(ii->user_ctx)
        ii->free_user_ctx(ii->user_ctx,ii->user_ctx);
    
    free(ii);
}

static void *
_iterator_find(iterator_info *ii, const void *data)
{
    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_find"));
    
    if((NULL == ii) || (NULL == data))
        return NULL;

    return _iterator_get(ii, data);
}

static void *
_iterator_find_next(iterator_info *ii, const void *data)
{
    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_find_next"));
    
    if(NULL == ii)
        return NULL;

    return _iterator_get_next(ii, data);
}

static int
_iterator_insert(iterator_info *ii, const void *data)
{
    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_insert"));
    
    if(NULL == ii)
        return -1;

    if(NULL == ii->insert_data)
        return -1;

    return ii->insert_data(ii->user_ctx, data);
}

static int
_iterator_remove(iterator_info *ii, const void *data)
{
    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_remove"));
    
    if(NULL == ii)
        return -1;

    if(NULL == ii->remove_data)
        return -1;

    return ii->remove_data(ii->user_ctx, data);
}

static int
_iterator_release(iterator_info *ii, const void *data)
{
    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_release"));
    
    if(NULL == ii)
        return -1;

    if(NULL == ii->release_data)
        return -1;

    return ii->release_data(ii->user_ctx, data);
}

static size_t
_iterator_size(iterator_info *ii)
{
    size_t count = 0;
    int rc = SNMP_ERR_NOERROR;
    netsnmp_ref_void loop_ctx = { NULL };
    netsnmp_ref_void tmp = { NULL };

    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_size"));
    
    if(NULL == ii)
        return -1;

    if(NULL != ii->get_size)
        return ii->get_size(ii->user_ctx);

    /*
     * no get_size. loop and count ourselves
     */
    if(ii->init_loop_ctx)
        ii->init_loop_ctx(ii->user_ctx, &loop_ctx);
    
    for( rc = ii->get_first(ii->user_ctx, &loop_ctx, &tmp);
         NULL != tmp.val;
         rc = ii->get_next(ii->user_ctx, &loop_ctx, &tmp) )
        ++count;

    if(ii->cleanup_loop_ctx)
        ii->cleanup_loop_ctx(ii->user_ctx,&loop_ctx);

    return count;
}

static void
_iterator_for_each(iterator_info *ii, netsnmp_container_obj_func *f,
                   void *ctx)
{
    int rc = SNMP_ERR_NOERROR;
    netsnmp_ref_void loop_ctx = { NULL };
    netsnmp_ref_void tmp = { NULL };

    DEBUGMSGT(("container_iterator",">%s\n", "_iterator_foreach"));
    
    if(NULL == ii)
        return;

    if(ii->init_loop_ctx)
        ii->init_loop_ctx(ii->user_ctx, &loop_ctx);
    
    for( rc = ii->get_first(ii->user_ctx, &loop_ctx, &tmp);
         NULL != tmp.val;
         rc = ii->get_next(ii->user_ctx, &loop_ctx, &tmp) )
        (*f) (tmp.val, ctx);

    if(ii->cleanup_loop_ctx)
        ii->cleanup_loop_ctx(ii->user_ctx,&loop_ctx);
}

static void
_iterator_clear(netsnmp_container *container, netsnmp_container_obj_func *f,
                 void *context)
{
    snmp_log(LOG_WARNING,"clear is meaningless for iterator container.\n");
}

/**********************************************************************
 *
 */
netsnmp_container*
netsnmp_container_iterator_get(void *iterator_user_ctx,
                               netsnmp_container_compare * compare,
                               Netsnmp_Iterator_Loop_Key * get_first,
                               Netsnmp_Iterator_Loop_Key * get_next,
                               Netsnmp_Iterator_Loop_Data * get_data,
                               Netsnmp_Iterator_Ctx_Dup * save_pos,
                               Netsnmp_Iterator_Ctx * init_loop_ctx,
                               Netsnmp_Iterator_Ctx * cleanup_loop_ctx,
                               Netsnmp_Iterator_Data * free_user_ctx,
                               int sorted)
{
    iterator_info *ii;

    /*
     * sanity checks
     */
    if(get_data && ! save_pos) {
        snmp_log(LOG_ERR, "save_pos required with get_data\n");
        return NULL;
    }

    /*
     * allocate memory
     */
    ii = SNMP_MALLOC_TYPEDEF(iterator_info);
    if (NULL==ii) {
        snmp_log(LOG_ERR, "couldn't allocate memory\n");
        return NULL;
    }

    /*
     * init container structure with iterator functions
     */
    ii->c.cfree = (netsnmp_container_rc*)_iterator_free;
    ii->c.compare = compare;
    ii->c.get_size = (netsnmp_container_size*)_iterator_size;
    ii->c.init = NULL;
    ii->c.insert = (netsnmp_container_op*)_iterator_insert;
    ii->c.remove = (netsnmp_container_op*)_iterator_remove;
    ii->c.release = (netsnmp_container_op*)_iterator_release;
    ii->c.find = (netsnmp_container_rtn*)_iterator_find;
    ii->c.find_next = (netsnmp_container_rtn*)_iterator_find_next;
    ii->c.get_subset = NULL;
    ii->c.get_iterator = NULL;
    ii->c.for_each = (netsnmp_container_func*)_iterator_for_each;
    ii->c.clear = _iterator_clear;

    /*
     * init iterator structure with user functions
     */
    ii->get_first = get_first;
    ii->get_next = get_next;
    ii->get_data = get_data;
    ii->save_pos = save_pos;
    ii->init_loop_ctx = init_loop_ctx;
    ii->cleanup_loop_ctx = cleanup_loop_ctx;
    ii->free_user_ctx = free_user_ctx;
    ii->sorted = sorted;

    ii->user_ctx = iterator_user_ctx;

    return (netsnmp_container*)ii;
}

void
netsnmp_container_iterator_set_data_cb(netsnmp_container *c,
                                       Netsnmp_Iterator_Data * insert_data,
                                       Netsnmp_Iterator_Data * remove_data,
                                       Netsnmp_Iterator_Op * get_size)
{
    iterator_info *ii = (iterator_info *)c;
    if(NULL == ii)
        return;
    
    ii->insert_data = insert_data;
    ii->remove_data = remove_data;
    ii->get_size = get_size;
}
