#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/stash_cache.h>
#include <net-snmp/agent/stash_to_next.h>

/** @defgroup stash_to_next stash_to_next
 *  Convert GET_STASH requests into GETNEXT requests for the handler.
 *  The purpose of this handler is to convert a GET_STASH auto-cache request
 *  to a series of GETNEXT requests.  It can be inserted into a handler chain
 *  where the lower-level handlers don't process such requests themselves.
 *  @ingroup utilities
 *  @{
 */

/** returns a stash_to_next handler that can be injected into a given
 *  handler chain.
 */
netsnmp_mib_handler *
netsnmp_get_stash_to_next_handler(void)
{
    netsnmp_mib_handler *handler =
        netsnmp_create_handler("stash_to_next",
                               netsnmp_stash_to_next_helper);

    if (NULL != handler)
        handler->flags |= MIB_HANDLER_AUTO_NEXT;

    return handler;
}

/** @internal Implements the stash_to_next handler */
int
netsnmp_stash_to_next_helper(netsnmp_mib_handler *handler,
                            netsnmp_handler_registration *reginfo,
                            netsnmp_agent_request_info *reqinfo,
                            netsnmp_request_info *requests)
{

    int             ret = SNMP_ERR_NOERROR;
    int             namelen;
    int             finished = 0;
    netsnmp_oid_stash_node **cinfo;
    netsnmp_variable_list   *vb;
    netsnmp_request_info    *reqtmp;

    /*
     * this code depends on AUTO_NEXT being set
     */
    netsnmp_assert(handler->flags & MIB_HANDLER_AUTO_NEXT);

    /*
     * Don't do anything for any modes except GET_STASH. Just return,
     * and the agent will call the next handler (AUTO_NEXT).
     *
     * If the handler chain already supports GET_STASH, we don't
     * need to do anything here either.  Once again, we just return
     * and the agent will call the next handler (AUTO_NEXT).
     *
     * Otherwise, we munge the mode to GET_NEXT, and call the
     * next handler ourselves, repeatedly until we've retrieved the
     * full contents of the table or subtree.
     *   Then restore the mode and return to the calling handler 
     * (setting AUTO_NEXT_OVERRRIDE so the agent knows what we did).
     */
    if (MODE_GET_STASH == reqinfo->mode) {
        if ( reginfo->modes & HANDLER_CAN_STASH ) {
            return ret;
        }
        cinfo  = netsnmp_extract_stash_cache( reqinfo );
        reqtmp = SNMP_MALLOC_TYPEDEF(netsnmp_request_info);
        vb = reqtmp->requestvb = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
        vb->type = ASN_NULL;
        snmp_set_var_objid( vb, reginfo->rootoid, reginfo->rootoid_len );

        reqinfo->mode = MODE_GETNEXT;
        while (!finished) {
            ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, reqtmp);
            namelen = SNMP_MIN(vb->name_length, reginfo->rootoid_len);
            if ( !snmp_oid_compare( reginfo->rootoid, reginfo->rootoid_len,
                                   vb->name, namelen) &&
                 vb->type != ASN_NULL && vb->type != SNMP_ENDOFMIBVIEW ) {
                /*
                 * This result is relevant so save it, and prepare
                 * the request varbind for the next query.
                 */
                netsnmp_oid_stash_add_data( cinfo, vb->name, vb->name_length,
                                            snmp_clone_varbind( vb ));
                    /*
                     * Tidy up the response structure,
                     *  ready for retrieving the next entry
                     */
                netsnmp_free_all_list_data(reqtmp->parent_data);
                reqtmp->parent_data = NULL;
                reqtmp->processed = 0;
                vb->type = ASN_NULL;
            } else {
                finished = 1;
            }
        }
        reqinfo->mode = MODE_GET_STASH;

        /*
         * let the handler chain processing know that we've already
         * called the next handler
         */
        handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
    }

    return ret;
}
/**  @} */

