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

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

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

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

#include <net-snmp/agent/table.h>
#include <net-snmp/agent/table_container.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);
}

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

/** @} */
