/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.17 $ of : mfd-data-access.m2c,v $ 
 *
 * $Id$
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "ipAddressPrefixTable.h"


#include "ipAddressPrefixTable_data_access.h"

#include "ip-mib/ipAddressTable/ipAddressTable.h"

/** @ingroup interface 
 * @addtogroup data_access data_access: Routines to access data
 *
 * These routines are used to locate the data used to satisfy
 * requests.
 * 
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table ipAddressPrefixTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::ipAddressPrefixTable is subid 32 of ip.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.32, length: 8
 */

/**
 * initialization for ipAddressPrefixTable data access
 *
 * This function is called during startup to allow you to
 * allocate any resources you need for the data table.
 *
 * @param ipAddressPrefixTable_reg
 *        Pointer to ipAddressPrefixTable_registration
 *
 * @retval MFD_SUCCESS : success.
 * @retval MFD_ERROR   : unrecoverable error.
 */
int
ipAddressPrefixTable_init_data(ipAddressPrefixTable_registration *
                               ipAddressPrefixTable_reg)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_init_data", "called\n"));

    /*
     * TODO:303:o: Initialize ipAddressPrefixTable data.
     */

    return MFD_SUCCESS;
}                               /* ipAddressPrefixTable_init_data */

/**
 * container overview
 *
 */

/**
 * container initialization
 *
 * @param container_ptr_ptr A pointer to a container pointer. If you
 *        create a custom container, use this parameter to return it
 *        to the MFD helper. If set to NULL, the MFD helper will
 *        allocate a container for you.
 * @param  cache A pointer to a cache structure. You can set the timeout
 *         and other cache flags using this pointer.
 *
 *  This function is called at startup to allow you to customize certain
 *  aspects of the access method. For the most part, it is for advanced
 *  users. The default code should suffice for most cases. If no custom
 *  container is allocated, the MFD code will create one for your.
 *
 *  This is also the place to set up cache behavior. The default, to
 *  simply set the cache timeout, will work well with the default
 *  container. If you are using a custom container, you may want to
 *  look at the cache helper documentation to see if there are any
 *  flags you want to set.
 *
 * @remark
 *  This would also be a good place to do any initialization needed
 *  for you data source. For example, opening a connection to another
 *  process that will supply the data, opening a database, etc.
 */
void
ipAddressPrefixTable_container_init(netsnmp_container **container_ptr_ptr,
                                    netsnmp_cache * cache)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_container_init", "called\n"));

    if (NULL == container_ptr_ptr) {
        snmp_log(LOG_ERR,
                 "bad container param to ipAddressPrefixTable_container_init\n");
        return;
    }

    /*
     * For advanced users, you can use a custom container. If you
     * do not create one, one will be created for you.
     */
    *container_ptr_ptr = NULL;

    if (NULL == cache) {
        snmp_log(LOG_ERR,
                 "bad cache param to ipAddressPrefixTable_container_init\n");
        return;
    }

    /*
     * TODO:345:A: Set up ipAddressPrefixTable cache properties.
     *
     * Also for advanced users, you can set parameters for the
     * cache. Do not change the magic pointer, as it is used
     * by the MFD helper. To completely disable caching, set
     * cache->enabled to 0.
     */
    cache->timeout = IPADDRESSPREFIXTABLE_CACHE_TIMEOUT;        /* seconds */
}                               /* ipAddressPrefixTable_container_init */

/**
 * container shutdown
 *
 * @param container_ptr A pointer to the container.
 *
 *  This function is called at shutdown to allow you to customize certain
 *  aspects of the access method. For the most part, it is for advanced
 *  users. The default code should suffice for most cases.
 *
 *  This function is called before ipAddressPrefixTable_container_free().
 *
 * @remark
 *  This would also be a good place to do any cleanup needed
 *  for you data source. For example, closing a connection to another
 *  process that supplied the data, closing a database, etc.
 */
void
ipAddressPrefixTable_container_shutdown(netsnmp_container *container_ptr)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_container_shutdown", "called\n"));

    if (NULL == container_ptr) {
        snmp_log(LOG_ERR,
                 "bad params to ipAddressPrefixTable_container_shutdown\n");
        return;
    }

}                               /* ipAddressPrefixTable_container_shutdown */

/**
 * load initial data
 *
 * TODO:350:M: Implement ipAddressPrefixTable data load
 * This function will also be called by the cache helper to load
 * the container again (after the container free function has been
 * called to free the previous contents).
 *
 * @param container container to which items should be inserted
 *
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source
 * @retval MFD_ERROR                : other error.
 *
 *  This function is called to load the index(es) (and data, optionally)
 *  for the every row in the data set.
 *
 * @remark
 *  While loading the data, the only important thing is the indexes.
 *  If access to your data is cheap/fast (e.g. you have a pointer to a
 *  structure in memory), it would make sense to update the data here.
 *  If, however, the accessing the data invovles more work (e.g. parsing
 *  some other existing data, or peforming calculations to derive the data),
 *  then you can limit yourself to setting the indexes and saving any
 *  information you will need later. Then use the saved information in
 *  ipAddressPrefixTable_row_prep() for populating data.
 *
 * @note
 *  If you need consistency between rows (like you want statistics
 *  for each row to be from the same time frame), you should set all
 *  data here.
 *
 */
int
ipAddressPrefixTable_container_load(netsnmp_container *container)
{
    ipAddressPrefixTable_rowreq_ctx *rowreq_ctx = NULL, *tmp_rowreq_ctx;
    ipAddressTable_rowreq_ctx *addr_rowreq_ctx;
    netsnmp_container *addr_container;
    netsnmp_iterator *addr_it;
    size_t          count = 0;
    u_char          tmp_pfx[NETSNMP_ACCESS_IPADDRESS_BUF_SIZE];

    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_container_load", "called\n"));

    addr_container = ipAddressTable_container_get();
    if (NULL == addr_container) {
        DEBUGMSGTL(("ipAddressPrefixTable:container_load",
                    "couldn't get ipAddress container\n"));
        return MFD_RESOURCE_UNAVAILABLE;
    }

    addr_it = CONTAINER_ITERATOR(addr_container);
    if (NULL == addr_container) {
        DEBUGMSGTL(("ipAddressPrefixTable:container_load",
                    "couldn't get ipAddress iterator\n"));
        return MFD_RESOURCE_UNAVAILABLE;
    }

    /*
     * TODO:351:M: |-> Load/update data in the ipAddressPrefixTable container.
     * loop over your ipAddressPrefixTable data, allocate a rowreq context,
     * set the index(es) [and data, optionally] and insert into
     * the container.
     */
    for (addr_rowreq_ctx = ITERATOR_FIRST(addr_it);
         addr_rowreq_ctx; addr_rowreq_ctx = ITERATOR_NEXT(addr_it)) {



        /*
         * TODO:352:M: |   |-> set indexes in new ipAddressPrefixTable rowreq context.
         * data context will be set from the param (unless NULL,
         *      in which case a new data context will be allocated)
         */
        if (NULL == rowreq_ctx) {
            rowreq_ctx = ipAddressPrefixTable_allocate_rowreq_ctx(NULL);
            if (NULL == rowreq_ctx) {
                snmp_log(LOG_ERR, "memory allocation failed\n");
                return MFD_RESOURCE_UNAVAILABLE;
            }
        }
        netsnmp_ipaddress_prefix_copy(tmp_pfx,
                                      addr_rowreq_ctx->tbl_idx.
                                      ipAddressAddr,
                                      addr_rowreq_ctx->data->
                                      ia_address_len,
                                      addr_rowreq_ctx->data->
                                      ia_prefix_len);
        if (MFD_SUCCESS !=
            ipAddressPrefixTable_indexes_set(rowreq_ctx,
                                             addr_rowreq_ctx->data->
                                             if_index,
                                             addr_rowreq_ctx->tbl_idx.
                                             ipAddressAddrType, tmp_pfx,
                                             addr_rowreq_ctx->data->
                                             ia_address_len,
                                             addr_rowreq_ctx->data->
                                             ia_prefix_len)) {
            snmp_log(LOG_ERR,
                     "error setting index while loading "
                     "ipAddressPrefixTable data.\n");
            ipAddressPrefixTable_release_rowreq_ctx(rowreq_ctx);
            rowreq_ctx = NULL;
            continue;
        }

        /** do we already have this prefix? */
        tmp_rowreq_ctx = CONTAINER_FIND(container, rowreq_ctx);
        if (NULL != tmp_rowreq_ctx)
            continue;

        /*
         * TODO:352:r: |   |-> populate ipAddressPrefixTable data context.
         * Populate data context here. (optionally, delay until row prep)
         */
        rowreq_ctx->data.ipAddressPrefixOrigin =
            addr_rowreq_ctx->data->ia_origin;

        /** defer the rest til row prep */

        /*
         * insert into table container, clear ptr so we reallocate
         */
        CONTAINER_INSERT(container, rowreq_ctx);
        rowreq_ctx = NULL;
        ++count;
    }
    ITERATOR_RELEASE(addr_it);

    DEBUGMSGT(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_container_load", "inserted %d records\n", count));

    return MFD_SUCCESS;
}                               /* ipAddressPrefixTable_container_load */

/**
 * container clean up
 *
 * @param container container with all current items
 *
 *  This optional callback is called prior to all
 *  item's being removed from the container. If you
 *  need to do any processing before that, do it here.
 *
 * @note
 *  The MFD helper will take care of releasing all the row contexts.
 *
 */
void
ipAddressPrefixTable_container_free(netsnmp_container *container)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_container_free", "called\n"));

    /*
     * TODO:380:M: Free ipAddressPrefixTable container data.
     */
}                               /* ipAddressPrefixTable_container_free */

/**
 * prepare row for processing.
 *
 *  When the agent has located the row for a request, this function is
 *  called to prepare the row for processing. If you fully populated
 *  the data context during the index setup phase, you may not need to
 *  do anything.
 *
 * @param rowreq_ctx pointer to a context.
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 */
int
ipAddressPrefixTable_row_prep(ipAddressPrefixTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_row_prep", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:390:o: Prepare row for request.
     * If populating row data was delayed, this is the place to
     * fill in the row for this request.
     */
    if (INETADDRESSTYPE_IPV6 == rowreq_ctx->tbl_idx.ipAddressPrefixType) {

    }

    return MFD_SUCCESS;
}                               /* ipAddressPrefixTable_row_prep */

/** @} */
