/*
 * table_row.c
 *
 * Helper for registering single row slices of a shared table
 *
 * $Id$
 */
#define TABLE_ROW_DATA  "table_row"

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

/** @defgroup table_row table_row
 *  Helps you implement a table shared across two or more subagents,
 *  or otherwise split into individual row slices.
 *  @ingroup table
 *
 * @{
 */

static Netsnmp_Node_Handler _table_row_handler;
static Netsnmp_Node_Handler _table_row_default_handler;

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

/* ==================================
 *
 * Table Row API: Table maintenance
 *
 * This helper doesn't operate with the complete
 *   table, so these routines are not relevant.
 *
 * ================================== */


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

/** returns a netsnmp_mib_handler object for the table_container helper */
netsnmp_mib_handler *
netsnmp_table_row_handler_get(void *row)
{
    netsnmp_mib_handler *handler;

    handler = netsnmp_create_handler("table_row",
                                     _table_row_handler);
    if(NULL == handler) {
        snmp_log(LOG_ERR,
                 "malloc failure in netsnmp_table_row_register\n");
        return NULL;
    }

    handler->myvoid = (void*)row;
    handler->flags |= MIB_HANDLER_INSTANCE;
 /* handler->flags |= MIB_HANDLER_AUTO_NEXT;  ??? */
    
    return handler;
}

int
netsnmp_table_row_register(netsnmp_handler_registration *reginfo,
                           netsnmp_table_registration_info *tabreg,
                           void *row, netsnmp_variable_list *index)
{
    netsnmp_handler_registration *reg2;
    netsnmp_mib_handler *handler;
    oid    row_oid[MAX_OID_LEN];
    size_t row_oid_len, len;
    char   tmp[SNMP_MAXBUF_MEDIUM];

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

        /*
         *   The first table_row invoked for a particular table should
         * register the full table as well, with a default handler to
         * process requests for non-existent (or incomplete) rows.
         *
         *   Subsequent table_row registrations attempting to set up
         * this default handler would fail - preferably silently!
         */
    snprintf(tmp, sizeof(tmp), "%s_table", reginfo->handlerName);
    reg2 = netsnmp_create_handler_registration(
              tmp,     _table_row_default_handler,
              reginfo->rootoid, reginfo->rootoid_len,
              reginfo->modes);
    netsnmp_register_table(reg2, tabreg);  /* Ignore return value */

        /*
         * Adjust the OID being registered, to take account
         * of the indexes and column range provided....
         */
    row_oid_len = reginfo->rootoid_len;
    memcpy( row_oid, (u_char *) reginfo->rootoid, row_oid_len * sizeof(oid));
    row_oid[row_oid_len++] = 1;   /* tableEntry */
    row_oid[row_oid_len++] = tabreg->min_column;
    reginfo->range_ubound  = tabreg->max_column;
    reginfo->range_subid   = row_oid_len-1;
    build_oid_noalloc(&row_oid[row_oid_len],
                      MAX_OID_LEN-row_oid_len, &len, NULL, 0, index);
    row_oid_len += len;
    free(reginfo->rootoid);
    reginfo->rootoid = netsnmp_memdup(row_oid, row_oid_len * sizeof(oid));
    reginfo->rootoid_len = row_oid_len;

     
        /*
         * ... insert a minimal handler ...
         */
    handler = netsnmp_table_row_handler_get(row);
    netsnmp_inject_handler(reginfo, handler );

        /*
         * ... and register the row
         */
    return netsnmp_register_handler(reginfo);
}


/** return the row data structure supplied to the table_row helper */
void *
netsnmp_table_row_extract(netsnmp_request_info *request)
{
    return netsnmp_request_get_list_data(request, TABLE_ROW_DATA);
}
/** @cond */

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * netsnmp_table_row_helper_handler()                           *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/

static int
_table_row_handler(netsnmp_mib_handler          *handler,
                   netsnmp_handler_registration *reginfo,
                   netsnmp_agent_request_info   *reqinfo,
                   netsnmp_request_info         *requests)
{
    int             rc = SNMP_ERR_NOERROR;
    netsnmp_request_info *req;
    void                 *row;

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

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

    /*
     * First off, get our pointer from the handler.
     * This contains the row that was actually registered.
     * Make this available for each of the requests passed in.
     */
    row = handler->myvoid;
    for (req = requests; req; req=req->next)
        netsnmp_request_add_list_data(req,
                netsnmp_create_data_list(TABLE_ROW_DATA, row, NULL));

    /*
     * Then call the next handler, to actually process the request
     */
    rc = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
    if (rc != SNMP_ERR_NOERROR) {
        DEBUGMSGTL(("table_row", "next handler returned %d\n", rc));
    }

    return rc;
}

static int
_table_row_default_handler(netsnmp_mib_handler  *handler,
                   netsnmp_handler_registration *reginfo,
                   netsnmp_agent_request_info   *reqinfo,
                   netsnmp_request_info         *requests)
{
    netsnmp_request_info       *req;
    netsnmp_table_request_info *table_info;
    netsnmp_table_registration_info *tabreg;

    tabreg = netsnmp_find_table_registration_info(reginfo);
    for ( req=requests; req; req=req->next ) {
        table_info = netsnmp_extract_table_info( req );
        if (( table_info->colnum >= tabreg->min_column ) ||
            ( table_info->colnum <= tabreg->max_column )) {
            netsnmp_set_request_error( reqinfo, req, SNMP_NOSUCHINSTANCE );
        } else {
            netsnmp_set_request_error( reqinfo, req, SNMP_NOSUCHOBJECT );
        }
    }
    return SNMP_ERR_NOERROR;
}
/** @endcond */


/* ==================================
 *
 * Table Row API: Row operations
 *
 * This helper doesn't operate with the complete
 *   table, so these routines are not relevant.
 *
 * ================================== */


/* ==================================
 *
 * Table Row API: Index operations
 *
 * This helper doesn't operate with the complete
 *   table, so these routines are not relevant.
 *
 * ================================== */

/** @} */
