/*
 * table_container.c
 * $Id$
 */

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

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include <net-snmp/agent/table_container.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#include <net-snmp/agent/table.h>
#include <net-snmp/library/container.h>
#include <net-snmp/library/snmp_assert.h>

/*
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_BEGIN        -1 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE1     0 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE2     1 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_ACTION       2 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_COMMIT       3 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_FREE         4 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_UNDO         5 
 */

/*
 * PRIVATE structure for holding important info for each table.
 */
typedef struct container_table_data_s {

   /** registration info for the table */
    netsnmp_table_registration_info *tblreg_info;

   /** container for the table rows */
   netsnmp_container          *table;

    /*
     * mutex_type                lock;
     */

   /* what type of key do we want? */
   char            key_type;

} container_table_data;

/** @defgroup table_container table_container
 *  Helps you implement a table when data can be found via a netsnmp_container.
 *  @ingroup table
 *
 *  The table_container handler is used (automatically) in conjuntion
 *  with the @link table table@endlink handler.
 *
 *  This handler will use the index information provided by
 *  the @link table @endlink handler to find the row needed to process
 *  the request.
 *
 *  The container must use one of 3 key types. It is the sub-handler's
 *  responsibility to ensure that the container and key type match (unless
 *  neither is specified, in which case a default will be used.)
 *
 *  The current key types are:
 *
 *    TABLE_CONTAINER_KEY_NETSNMP_INDEX
 *        The container should do comparisons based on a key that may be cast
 *        to a netsnmp index (netsnmp_index *). This index contains only the
 *        index portion of the OID, not the entire OID.
 *
 *    TABLE_CONTAINER_KEY_VARBIND_INDEX
 *        The container should do comparisons based on a key that may be cast
 *        to a netsnmp variable list (netsnmp_variable_list *). This variable
 *        list will contain one varbind for each index component.
 *
 *    TABLE_CONTAINER_KEY_VARBIND_RAW    (NOTE: unimplemented)
 *        While not yet implemented, future plans include passing the request
 *        varbind with the full OID to a container.
 *
 *  If a key type is not specified at registration time, the default key type
 *  of TABLE_CONTAINER_KEY_NETSNMP_INDEX will be used. If a container is
 *  provided, or the handler name is aliased to a container type, the container
 *  must use a netsnmp index.
 *
 *  If no container is provided, a lookup will be made based on the
 *  sub-handler's name, or if that isn't found, "table_container". The 
 *  table_container key type will be netsnmp_index.
 *
 *  The container must, at a minimum, implement find and find_next. If a NULL
 *  key is passed to the container, it must return the first item, if any.
 *  All containers provided by net-snmp fulfil this requirement.
 *
 *  This handler will only register to process 'data lookup' modes. In
 *  traditional net-snmp modes, that is any GET-like mode (GET, GET-NEXT,
 *  GET-BULK) or the first phase of a SET (RESERVE1). In the new baby-steps
 *  mode, DATA_LOOKUP is it's own mode, and is a pre-cursor to other modes.
 *
 *  When called, the handler will call the appropriate container method
 *  with the appropriate key type. If a row was not found, the result depends
 *  on the mode.
 *
 *  GET Processing
 *    An exact match must be found. If one is not, the error NOSUCHINSTANCE
 *    is set.
 *
 *  GET-NEXT / GET-BULK
 *    If no row is found, the column number will be increased (using any
 *    valid_columns structure that may have been provided), and the first row
 *    will be retrieved. If no first row is found, the processed flag will be
 *    set, so that the sub-handler can skip any processing related to the
 *    request. The agent will notice this unsatisfied request, and attempt to
 *    pass it to the next appropriate handler.
 *
 *  SET
 *    If the hander did not register with the HANDLER_CAN_NOT_CREATE flag
 *    set in the registration modes, it is assumed that this is a row
 *    creation request and a NULL row is added to the request's data list.
 *    The sub-handler is responsbile for dealing with any row creation
 *    contraints and inserting any newly created rows into the container
 *    and the request's data list.
 *
 *  If a row is found, it will be inserted into
 *  the request's data list. The sub-handler may retrieve it by calling
 *      netsnmp_container_table_extract_context(request); *
 *  NOTE NOTE NOTE:
 *
 *  This helper and it's API are still being tested and are subject to change.
 *
 * @{
 */

static int
_container_table_handler(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *agtreq_info,
                         netsnmp_request_info *requests);

static void *
_find_next_row(netsnmp_container *c,
               netsnmp_table_request_info *tblreq,
               void * key);

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * PUBLIC Registration functions                                      *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/

/* ==================================
 *
 * Container Table API: Table maintenance
 *
 * ================================== */

container_table_data *
netsnmp_tcontainer_create_table( const char *name,
                                 netsnmp_container *container, long flags )
{
    container_table_data *table;

    table = SNMP_MALLOC_TYPEDEF(container_table_data);
    if (!table)
        return NULL;
    if (container)
        table->table = container;
    else {
        table->table = netsnmp_container_find("table_container");
        if (!table->table) {
            SNMP_FREE(table);
            return NULL;
        }
    }

    if (flags)
        table->key_type = flags & 0x03;  /* Use lowest two bits */
    else
        table->key_type = TABLE_CONTAINER_KEY_NETSNMP_INDEX;

    if (!table->table->compare)
         table->table->compare  = netsnmp_compare_netsnmp_index;
    if (!table->table->ncompare)
         table->table->ncompare = netsnmp_ncompare_netsnmp_index;

    return table;
}

void
netsnmp_tcontainer_delete_table( container_table_data *table )
{
    if (!table)
       return;

    if (table->table)
       CONTAINER_FREE(table->table);
    
    SNMP_FREE(table);
    return;
}

    /*
     * The various standalone row operation routines
     *    (create/clone/copy/delete)
     * will be specific to a particular table,
     *    so can't be implemented here.
     */

int
netsnmp_tcontainer_add_row( container_table_data *table, netsnmp_index *row )
{
    if (!table || !table->table || !row)
        return -1;
    CONTAINER_INSERT( table->table, row );
    return 0;
}

netsnmp_index *
netsnmp_tcontainer_remove_row( container_table_data *table, netsnmp_index *row )
{
    if (!table || !table->table || !row)
        return NULL;
    CONTAINER_REMOVE( table->table, row );
    return NULL;
}

int
netsnmp_tcontainer_replace_row( container_table_data *table,
                                netsnmp_index *old_row, netsnmp_index *new_row )
{
    if (!table || !table->table || !old_row || !new_row)
        return -1;
    netsnmp_tcontainer_remove_row( table, old_row );
    netsnmp_tcontainer_add_row(    table, new_row );
    return 0;
}

    /* netsnmp_tcontainer_remove_delete_row() will be table-specific too */


/* ==================================
 *
 * Container Table API: MIB maintenance
 *
 * ================================== */

/** returns a netsnmp_mib_handler object for the table_container helper */
netsnmp_mib_handler *
netsnmp_container_table_handler_get(netsnmp_table_registration_info *tabreg,
                                    netsnmp_container *container, char key_type)
{
    container_table_data *tad;
    netsnmp_mib_handler *handler;

    if (NULL == tabreg) {
        snmp_log(LOG_ERR, "bad param in netsnmp_container_table_register\n");
        return NULL;
    }

    tad = SNMP_MALLOC_TYPEDEF(container_table_data);
    handler = netsnmp_create_handler("table_container",
                                     _container_table_handler);
    if((NULL == tad) || (NULL == handler)) {
        if(tad) free(tad); /* SNMP_FREE wasted on locals */
        if(handler) free(handler); /* SNMP_FREE wasted on locals */
        snmp_log(LOG_ERR,
                 "malloc failure in netsnmp_container_table_register\n");
        return NULL;
    }

    tad->tblreg_info = tabreg;  /* we need it too, but it really is not ours */
    if(key_type)
        tad->key_type = key_type;
    else
        tad->key_type = TABLE_CONTAINER_KEY_NETSNMP_INDEX;

    if(NULL == container)
        container = netsnmp_container_find("table_container");
    tad->table = container;

    if (NULL==container->compare)
        container->compare = netsnmp_compare_netsnmp_index;
    if (NULL==container->ncompare)
        container->ncompare = netsnmp_ncompare_netsnmp_index;
    
    handler->myvoid = (void*)tad;
    handler->flags |= MIB_HANDLER_AUTO_NEXT;
    
    return handler;
}

int
netsnmp_container_table_register(netsnmp_handler_registration *reginfo,
                                 netsnmp_table_registration_info *tabreg,
                                 netsnmp_container *container, char key_type )
{
    netsnmp_mib_handler *handler;

    if ((NULL == reginfo) || (NULL == reginfo->handler) || (NULL == tabreg)) {
        snmp_log(LOG_ERR, "bad param in netsnmp_container_table_register\n");
        return SNMPERR_GENERR;
    }

    if (NULL==container)
        container = netsnmp_container_find(reginfo->handlerName);

    handler = netsnmp_container_table_handler_get(tabreg, container, key_type);
    netsnmp_inject_handler(reginfo, handler );

    return netsnmp_register_table(reginfo, tabreg);
}

int
netsnmp_container_table_unregister(netsnmp_handler_registration *reginfo)
{
    container_table_data *tad;

    if (!reginfo)
        return MIB_UNREGISTRATION_FAILED;
    tad = (container_table_data *)
        netsnmp_find_handler_data_by_name(reginfo, "table_container");
    if (tad) {
        CONTAINER_FREE( tad->table );
        tad->table = NULL;
        free(tad);
        reginfo->handler->myvoid = NULL;
    }
    return netsnmp_unregister_table( reginfo );
}

/** retrieve the container used by the table_container helper */
netsnmp_container*
netsnmp_container_table_container_extract(netsnmp_request_info *request)
{
    return (netsnmp_container *)
         netsnmp_request_get_list_data(request, TABLE_CONTAINER_CONTAINER);
}

#ifndef NETSNMP_USE_INLINE
/** find the context data used by the table_container helper */
void *
netsnmp_container_table_row_extract(netsnmp_request_info *request)
{
    /*
     * NOTE: this function must match in table_container.c and table_container.h.
     *       if you change one, change them both!
     */
    return netsnmp_request_get_list_data(request, TABLE_CONTAINER_ROW);
}
/** find the context data used by the table_container helper */
void *
netsnmp_container_table_extract_context(netsnmp_request_info *request)
{
    /*
     * NOTE: this function must match in table_container.c and table_container.h.
     *       if you change one, change them both!
     */
    return netsnmp_request_get_list_data(request, TABLE_CONTAINER_ROW);
}
#endif /* inline */

/** inserts a newly created table_container entry into a request list */
void
netsnmp_container_table_row_insert(netsnmp_request_info *request,
                                   netsnmp_index        *row)
{
    netsnmp_request_info       *req;
    netsnmp_table_request_info *table_info = NULL;
    netsnmp_variable_list      *this_index = NULL;
    netsnmp_variable_list      *that_index = NULL;
    oid      base_oid[] = {0, 0};	/* Make sure index OIDs are legal! */
    oid      this_oid[MAX_OID_LEN];
    oid      that_oid[MAX_OID_LEN];
    size_t   this_oid_len, that_oid_len;

    if (!request)
        return;

    /*
     * We'll add the new row information to any request
     * structure with the same index values as the request
     * passed in (which includes that one!).
     *
     * So construct an OID based on these index values.
     */

    table_info = netsnmp_extract_table_info(request);
    this_index = table_info->indexes;
    build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len,
                      base_oid, 2, this_index);

    /*
     * We need to look through the whole of the request list
     * (as received by the current handler), as there's no
     * guarantee that this routine will be called by the first
     * varbind that refers to this row.
     *   In particular, a RowStatus controlled row creation
     * may easily occur later in the variable list.
     *
     * So first, we rewind to the head of the list....
     */
    for (req=request; req->prev; req=req->prev)
        ;

    /*
     * ... and then start looking for matching indexes
     * (by constructing OIDs from these index values)
     */
    for (; req; req=req->next) {
        if (req->processed) 
            continue;
        
        table_info = netsnmp_extract_table_info(req);
        that_index = table_info->indexes;
        build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len,
                          base_oid, 2, that_index);
      
        /*
         * This request has the same index values,
         * so add the newly-created row information.
         */
        if (snmp_oid_compare(this_oid, this_oid_len,
                             that_oid, that_oid_len) == 0) {
            netsnmp_request_add_list_data(req,
                netsnmp_create_data_list(TABLE_CONTAINER_ROW, row, NULL));
        }
    }
}

/** @cond */
/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * DATA LOOKUP functions                                              *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/
NETSNMP_STATIC_INLINE void
_set_key( container_table_data * tad, netsnmp_request_info *request,
          netsnmp_table_request_info *tblreq_info,
          void **key, netsnmp_index *index )
{
    if (TABLE_CONTAINER_KEY_NETSNMP_INDEX == tad->key_type) {
        index->oids = tblreq_info->index_oid;
        index->len = tblreq_info->index_oid_len;
        *key = index;
    }
    else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) {
        *key = tblreq_info->indexes;
    }
#if 0
    else if (TABLE_CONTAINER_KEY_VARBIND_RAW == tad->key_type) {
        *key = request->requestvb;
    }
#endif
    else
        *key = NULL;
}


NETSNMP_STATIC_INLINE void
_data_lookup(netsnmp_handler_registration *reginfo,
            netsnmp_agent_request_info *agtreq_info,
            netsnmp_request_info *request, container_table_data * tad)
{
    netsnmp_index *row = NULL;
    netsnmp_table_request_info *tblreq_info;
    netsnmp_variable_list *var;
    netsnmp_index index;
    void *key;

    var = request->requestvb;

    DEBUGIF("table_container") {
        DEBUGMSGTL(("table_container", "  data_lookup oid:"));
        DEBUGMSGOID(("table_container", var->name, var->name_length));
        DEBUGMSG(("table_container", "\n"));
    }

    /*
     * Get pointer to the table information for this request. This
     * information was saved by table_helper_handler.
     */
    tblreq_info = netsnmp_extract_table_info(request);
    /** the table_helper_handler should enforce column boundaries. */
    netsnmp_assert((NULL != tblreq_info) &&
                   (tblreq_info->colnum <= tad->tblreg_info->max_column));
    
    if ((agtreq_info->mode == MODE_GETNEXT) ||
        (agtreq_info->mode == MODE_GETBULK)) {
        /*
         * find the row. This will automatically move to the next
         * column, if necessary.
         */
        _set_key( tad, request, tblreq_info, &key, &index );
        row = _find_next_row(tad->table, tblreq_info, key);
        if (row) {
            /*
             * update indexes in tblreq_info (index & varbind),
             * then update request varbind oid
             */
            if(TABLE_CONTAINER_KEY_NETSNMP_INDEX == tad->key_type) {
                tblreq_info->index_oid_len = row->len;
                memcpy(tblreq_info->index_oid, row->oids,
                       row->len * sizeof(oid));
                netsnmp_update_variable_list_from_index(tblreq_info);
            }
            else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) {
                /** xxx-rks: shouldn't tblreq_info->indexes be updated
                    before we call this?? */
                netsnmp_update_indexes_from_variable_list(tblreq_info);
            }

            if (TABLE_CONTAINER_KEY_VARBIND_RAW != tad->key_type) {
                netsnmp_table_build_oid_from_index(reginfo, request,
                                                   tblreq_info);
            }
        }
        else {
            /*
             * no results found. Flag the request so lower handlers will
             * ignore it, but it is not an error - getnext will move
             * on to another handler to process this request.
             */
            netsnmp_set_request_error(agtreq_info, request, SNMP_ENDOFMIBVIEW);
            DEBUGMSGTL(("table_container", "no row found\n"));
        }
    } /** GETNEXT/GETBULK */
    else {

        _set_key( tad, request, tblreq_info, &key, &index );
        row = CONTAINER_FIND(tad->table, key);
        if (NULL == row) {
            /*
             * not results found. For a get, that is an error
             */
            DEBUGMSGTL(("table_container", "no row found\n"));
            if((agtreq_info->mode != MODE_SET_RESERVE1) || /* get */
               (reginfo->modes & HANDLER_CAN_NOT_CREATE)) { /* no create */
                netsnmp_set_request_error(agtreq_info, request,
                                          SNMP_NOSUCHINSTANCE);
            }
        }
    } /** GET/SET */
    
    /*
     * save the data and table in the request.
     */
    if (SNMP_ENDOFMIBVIEW != request->requestvb->type) {
        if (NULL != row)
            netsnmp_request_add_list_data(request,
                                          netsnmp_create_data_list
                                          (TABLE_CONTAINER_ROW,
                                           row, NULL));
        netsnmp_request_add_list_data(request,
                                      netsnmp_create_data_list
                                      (TABLE_CONTAINER_CONTAINER,
                                       tad->table, NULL));
    }
}

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * netsnmp_table_container_helper_handler()                           *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/
static int
_container_table_handler(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *agtreq_info,
                         netsnmp_request_info *requests)
{
    int             rc = SNMP_ERR_NOERROR;
    int             oldmode, need_processing = 0;
    container_table_data *tad;

    /** sanity checks */
    netsnmp_assert((NULL != handler) && (NULL != handler->myvoid));
    netsnmp_assert((NULL != reginfo) && (NULL != agtreq_info));

    DEBUGMSGTL(("table_container", "Mode %s, Got request:\n",
                se_find_label_in_slist("agent_mode",agtreq_info->mode)));

    /*
     * First off, get our pointer from the handler. This
     * lets us get to the table registration information we
     * saved in get_table_container_handler(), as well as the
     * container where the actual table data is stored.
     */
    tad = (container_table_data *)handler->myvoid;

    /*
     * only do data lookup for first pass
     *
     * xxx-rks: this should really be handled up one level. we should
     * be able to say what modes we want to be called for during table
     * registration.
     */
    oldmode = agtreq_info->mode;
    if(MODE_IS_GET(oldmode) || (MODE_SET_RESERVE1 == oldmode)) {
        netsnmp_request_info *curr_request;
        /*
         * Loop through each of the requests, and
         * try to find the appropriate row from the container.
         */
        for (curr_request = requests; curr_request; curr_request = curr_request->next) {
            /*
             * skip anything that doesn't need processing.
             */
            if (curr_request->processed != 0) {
                DEBUGMSGTL(("table_container", "already processed\n"));
                continue;
            }
            
            /*
             * find data for this request
             */
            _data_lookup(reginfo, agtreq_info, curr_request, tad);

            if(curr_request->processed)
                continue;

            ++need_processing;
        } /** for ( ... requests ... ) */
    }
    
    /*
     * send GET instead of GETNEXT to sub-handlers
     * xxx-rks: again, this should be handled further up.
     */
    if ((oldmode == MODE_GETNEXT) && (handler->next)) {
        /*
         * tell agent handlder not to auto call next handler
         */
        handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;

        /*
         * if we found rows to process, pretend to be a get request
         * and call handler below us.
         */
        if(need_processing > 0) {
            agtreq_info->mode = MODE_GET;
            rc = netsnmp_call_next_handler(handler, reginfo, agtreq_info,
                                           requests);
            if (rc != SNMP_ERR_NOERROR) {
                DEBUGMSGTL(("table_container",
                            "next handler returned %d\n", rc));
            }

            agtreq_info->mode = oldmode; /* restore saved mode */
        }
    }

    return rc;
}
/** @endcond */


/* ==================================
 *
 * Container Table API: Row operations
 *
 * ================================== */

static void *
_find_next_row(netsnmp_container *c,
               netsnmp_table_request_info *tblreq,
               void * key)
{
    void *row = NULL;

    if (!c || !tblreq || !tblreq->reg_info ) {
        snmp_log(LOG_ERR,"_find_next_row param error\n");
        return NULL;
    }

    /*
     * table helper should have made sure we aren't below our minimum column
     */
    netsnmp_assert(tblreq->colnum >= tblreq->reg_info->min_column);

    /*
     * if no indexes then use first row.
     */
    if(tblreq->number_indexes == 0) {
        row = CONTAINER_FIRST(c);
    } else {

        if(NULL == key) {
            netsnmp_index index;
            index.oids = tblreq->index_oid;
            index.len = tblreq->index_oid_len;
            row = CONTAINER_NEXT(c, &index);
        }
        else
            row = CONTAINER_NEXT(c, key);

        /*
         * we don't have a row, but we might be at the end of a
         * column, so try the next column.
         */
        if (NULL == row) {
            /*
             * don't set tblreq next_col unless we know there is one,
             * so we don't mess up table handler sparse table processing.
             */
            oid next_col = netsnmp_table_next_column(tblreq);
            if (0 != next_col) {
                tblreq->colnum = next_col;
                row = CONTAINER_FIRST(c);
            }
        }
    }
    
    return row;
}

/**
 * deprecated, backwards compatability only
 *
 * expected impact to remove: none
 *  - used between helpers, shouldn't have been used by end users
 *
 * replacement: none
 *  - never should have been a public method in the first place
 */
netsnmp_index *
netsnmp_table_index_find_next_row(netsnmp_container *c,
                                  netsnmp_table_request_info *tblreq)
{
    return _find_next_row(c, tblreq, NULL );
}

/* ==================================
 *
 * Container Table API: Index operations
 *
 * ================================== */

/** @} */
