#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/bulk_to_next.h>

/** @defgroup bulk_to_next bulk_to_next
 *  Convert GETBULK requests into GETNEXT requests for the handler.
 *  The only purpose of this handler is to convert a GETBULK request
 *  to a GETNEXT request.  It is inserted into handler chains where
 *  the handler has not set the HANDLER_CAN_GETBULK flag.
 *  @ingroup utilities
 *  @{
 */

/** returns a bulk_to_next handler that can be injected into a given
 *  handler chain.
 */
netsnmp_mib_handler *
netsnmp_get_bulk_to_next_handler(void)
{
    netsnmp_mib_handler *handler =
        netsnmp_create_handler("bulk_to_next",
                               netsnmp_bulk_to_next_helper);

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

    return handler;
}

/** takes answered requests and decrements the repeat count and
 *  updates the requests to the next to-do varbind in the list */
void
netsnmp_bulk_to_next_fix_requests(netsnmp_request_info *requests)
{
    netsnmp_request_info *request;
    /*
     * Make sure that:
     *    - repeats remain
     *    - last handler provided an answer
     *    - answer didn't exceed range end (ala check_getnext_results)
     *    - there is a next variable
     * then
     * update the varbinds for the next request series 
     */
    for (request = requests; request; request = request->next) {
        if (request->repeat > 0 &&
            request->requestvb->type != ASN_NULL &&
            request->requestvb->type != ASN_PRIV_RETRY &&
            (snmp_oid_compare(request->requestvb->name,
                              request->requestvb->name_length,
                              request->range_end,
                              request->range_end_len) < 0) &&
            request->requestvb->next_variable ) {
            request->repeat--;
            snmp_set_var_objid(request->requestvb->next_variable,
                               request->requestvb->name,
                               request->requestvb->name_length);
            request->requestvb = request->requestvb->next_variable;
            request->requestvb->type = ASN_PRIV_RETRY;
            /*
             * if inclusive == 2, it was set in check_getnext_results for
             * the previous requestvb. Now that we've moved on, clear it.
             */
            if (2 == request->inclusive)
                request->inclusive = 0;
        }
    }
}

/** @internal Implements the bulk_to_next handler */
int
netsnmp_bulk_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;

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

    /*
     * don't do anything for any modes besides GETBULK. Just return, and
     * the agent will call the next handler (AUTO_NEXT).
     *
     * for GETBULK, we munge the mode, call the next handler ourselves
     * (setting AUTO_NEXT_OVERRRIDE so the agent knows what we did),
     * restore the mode and fix up the requests.
     */
    if(MODE_GETBULK == reqinfo->mode) {

        DEBUGIF("bulk_to_next") {
            netsnmp_request_info *req = requests;
            while(req) {
                DEBUGMSGTL(("bulk_to_next", "Got request: "));
                DEBUGMSGOID(("bulk_to_next", req->requestvb->name,
                             req->requestvb->name_length));
                DEBUGMSG(("bulk_to_next", "\n"));
                req = req->next;
            }
        }

        reqinfo->mode = MODE_GETNEXT;
        ret =
            netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
        reqinfo->mode = MODE_GETBULK;

        /*
         * update the varbinds for the next request series 
         */
        netsnmp_bulk_to_next_fix_requests(requests);

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

    return ret;
}

/** initializes the bulk_to_next helper which then registers a bulk_to_next
 *  handler as a run-time injectable handler for configuration file
 *  use.
 */
void
netsnmp_init_bulk_to_next_helper(void)
{
    netsnmp_register_handler_by_name("bulk_to_next",
                                     netsnmp_get_bulk_to_next_handler());
}
/**  @} */

