/*
 * 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 "ipSystemStatsTable.h"


#include "ipSystemStatsTable_data_access.h"

static int      ipss_cache_refresh = IPSYSTEMSTATSTABLE_CACHE_TIMEOUT;

/** @ingroup interface 
 * @addtogroup data_access data_access: Routines to access data
 *
 * These routines are used to locate the data used to satisfy
 * requests.
 * 
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table ipSystemStatsTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::ipSystemStatsTable is subid 1 of ipTrafficStats.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.31.1, length: 9
 */

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

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

    netsnmp_access_systemstats_init();
    return MFD_SUCCESS;
}                               /* ipSystemStatsTable_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
ipSystemStatsTable_container_init(netsnmp_container **container_ptr_ptr,
                                  netsnmp_cache * cache)
{
    DEBUGMSGTL(("verbose:ipSystemStatsTable:ipSystemStatsTable_container_init", "called\n"));

    if (NULL == container_ptr_ptr) {
        snmp_log(LOG_ERR,
                 "bad container param to ipSystemStatsTable_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 = netsnmp_container_find("ipSystemStatsTable:table_container");

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

    /*
     * TODO:345:A: Set up ipSystemStatsTable 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 = IPSYSTEMSTATSTABLE_CACHE_TIMEOUT;  /* seconds */

    /*
     * don't release resources
     */
    cache->flags |=
        (NETSNMP_CACHE_DONT_AUTO_RELEASE | NETSNMP_CACHE_DONT_FREE_EXPIRED
         | NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD |
         NETSNMP_CACHE_AUTO_RELOAD);
    ipSystemStatsTable_container_load(*container_ptr_ptr);
}                               /* ipSystemStatsTable_container_init */

/**
 * check entry for update
 */
static void
_check_for_updates(ipSystemStatsTable_rowreq_ctx * rowreq_ctx,
                   netsnmp_container *stats)
{
    /*
     * check for matching entry. works because indexes are the same.
     */
    netsnmp_systemstats_entry *systemstats_entry =
        CONTAINER_FIND(stats, rowreq_ctx->data);
    if (NULL == systemstats_entry) {
        DEBUGMSGTL(("ipSystemStatsTable:access",
                    "updating missing entry\n"));

        /*
         * mark row as missing, so we can set discontinuity
         * when it comes back.
         *
         * what else should we do? set refresh to 0? that's not quite right...
         */
        rowreq_ctx->known_missing = 1;
    } else {
        DEBUGMSGTL(("ipSystemStatsTable:access",
                    "updating existing entry\n"));

        /*
         * Check for changes & update
         */
        netsnmp_access_systemstats_entry_update(rowreq_ctx->data,
                                                systemstats_entry);

        /*
         * set discontinuity if previously missing.
         */
        if (1 == rowreq_ctx->known_missing) {
            rowreq_ctx->known_missing = 0;
            rowreq_ctx->ipSystemStatsDiscontinuityTime =
                netsnmp_get_agent_uptime();
        }

        /*
         * remove entry from container
         */
        CONTAINER_REMOVE(stats, systemstats_entry);
        netsnmp_access_systemstats_entry_free(systemstats_entry);
    }
}

/**
 * add new entry
 */
static void
_add_new(netsnmp_systemstats_entry *systemstats_entry,
         netsnmp_container *container)
{
    ipSystemStatsTable_rowreq_ctx *rowreq_ctx;

    DEBUGMSGTL(("ipSystemStatsTable:access", "creating new entry\n"));

    netsnmp_assert(NULL != systemstats_entry);
    netsnmp_assert(NULL != container);

    /*
     * allocate an row context and set the index(es)
     */
    rowreq_ctx =
        ipSystemStatsTable_allocate_rowreq_ctx(systemstats_entry, NULL);
    if ((NULL != rowreq_ctx)
        && (MFD_SUCCESS ==
            ipSystemStatsTable_indexes_set(rowreq_ctx,
                                           systemstats_entry->
                                           index[0]))) {
        rowreq_ctx->ipSystemStatsRefreshRate = ipss_cache_refresh * 1000;       /* milli-seconds */
        CONTAINER_INSERT(container, rowreq_ctx);
    } else {
        if (NULL != rowreq_ctx) {
            snmp_log(LOG_ERR, "error setting index while loading "
                     "ipSystemStatsTable cache.\n");
            ipSystemStatsTable_release_rowreq_ctx(rowreq_ctx);
        } else {
            snmp_log(LOG_ERR, "memory allocation failed while loading "
                     "ipSystemStatsTable cache.\n");
            netsnmp_access_systemstats_entry_free(systemstats_entry);
        }
    }
}

/**
 * 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 ipSystemStatsTable_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
ipSystemStatsTable_container_shutdown(netsnmp_container *container_ptr)
{
    DEBUGMSGTL(("verbose:ipSystemStatsTable:ipSystemStatsTable_container_shutdown", "called\n"));

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

}                               /* ipSystemStatsTable_container_shutdown */

/**
 * load initial data
 *
 * TODO:350:M: Implement ipSystemStatsTable 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
 *  ipSystemStatsTable_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
ipSystemStatsTable_container_load(netsnmp_container *container)
{
    netsnmp_container *stats =
        netsnmp_access_systemstats_container_load(NULL, 0);


    DEBUGMSGTL(("verbose:ipSystemStatsTable:ipSystemStatsTable_cache_load",
                "called\n"));

    netsnmp_assert(NULL != container);

    if (NULL == stats)
        return MFD_RESOURCE_UNAVAILABLE;        /* msg already logged */
    /*
     * TODO:351:M: |-> Load/update data in the ipSystemStatsTable container.
     * loop over your ipSystemStatsTable data, allocate a rowreq context,
     * set the index(es) [and data, optionally] and insert into
     * the container.
     */
    /*
     * we just got a fresh copy of data. compare it to
     * what we've already got, and make any adjustements...
     */
    CONTAINER_FOR_EACH(container, (netsnmp_container_obj_func *)
                       _check_for_updates, stats);

    /*
     * now add any new entries
     */
    CONTAINER_FOR_EACH(stats, (netsnmp_container_obj_func *)
                       _add_new, container);

    /*
     * free the container. we've either claimed each ifentry, or released it,
     * so the dal function doesn't need to clear the container.
     */
    netsnmp_access_systemstats_container_free(stats,
                                              NETSNMP_ACCESS_SYSTEMSTATS_FREE_DONT_CLEAR);

    DEBUGMSGT(("verbose:ipSystemStatsTable:ipSystemStatsTable_cache_load",
               "%" NETSNMP_PRIz "u records\n", CONTAINER_SIZE(container)));

    return MFD_SUCCESS;
}                               /* ipSystemStatsTable_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
ipSystemStatsTable_container_free(netsnmp_container *container)
{
    DEBUGMSGTL(("verbose:ipSystemStatsTable:ipSystemStatsTable_container_free", "called\n"));

    /*
     * TODO:380:M: Free ipSystemStatsTable container data.
     */
}                               /* ipSystemStatsTable_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
ipSystemStatsTable_row_prep(ipSystemStatsTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipSystemStatsTable:ipSystemStatsTable_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.
     */

    return MFD_SUCCESS;
}                               /* ipSystemStatsTable_row_prep */

/** @} */
