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

#define MIB_CLIENTS_ARE_EVIL 1

/*
 * don't use these! 
 */
void            set_current_agent_session(netsnmp_agent_session *asp);
netsnmp_agent_session *netsnmp_get_current_agent_session(void);

/** @defgroup old_api old_api
 *  Calls mib module code written in the old style of code.
 *  @ingroup handler
 *  This is a backwards compatilibity module that allows code written
 *  in the old API to be run under the new handler based architecture.
 *  Use it by calling netsnmp_register_old_api().
 *  @{
 */

/** returns a old_api handler that should be the final calling
 * handler.  Don't use this function.  Use the netsnmp_register_old_api()
 * function instead.
 */
netsnmp_mib_handler *
get_old_api_handler(void)
{
    return netsnmp_create_handler("old_api", netsnmp_old_api_helper);
}


/** Registers an old API set into the mib tree.  Functionally this
 * mimics the old register_mib_context() function (and in fact the new
 * register_mib_context() function merely calls this new old_api one).
 */
int
netsnmp_register_old_api(const char *moduleName,
                         struct variable *var,
                         size_t varsize,
                         size_t numvars,
                         oid * mibloc,
                         size_t mibloclen,
                         int priority,
                         int range_subid,
                         oid range_ubound,
                         netsnmp_session * ss,
                         const char *context, int timeout, int flags)
{

    unsigned int    i;

    /*
     * register all subtree nodes 
     */
    for (i = 0; i < numvars; i++) {
        struct variable *vp;
        netsnmp_handler_registration *reginfo =
            SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);

        vp = netsnmp_memdup((const struct variable *)
                            ((const char *) var + varsize * i),
                            varsize);

        reginfo->handler = get_old_api_handler();
        reginfo->handlerName = strdup(moduleName);
        reginfo->rootoid_len = (mibloclen + vp->namelen);
        reginfo->rootoid =
            (oid *) malloc(reginfo->rootoid_len * sizeof(oid));

        memcpy(reginfo->rootoid, mibloc, mibloclen * sizeof(oid));
        memcpy(reginfo->rootoid + mibloclen, vp->name, vp->namelen
               * sizeof(oid));
        reginfo->handler->myvoid = (void *) vp;

        reginfo->priority = priority;
        reginfo->range_subid = range_subid;

        reginfo->range_ubound = range_ubound;
        reginfo->timeout = timeout;
        reginfo->contextName = (context) ? strdup(context) : NULL;
        reginfo->modes = HANDLER_CAN_RWRITE;

        /*
         * register ourselves in the mib tree 
         */
        if (netsnmp_register_handler(reginfo) != MIB_REGISTERED_OK) {
            /** netsnmp_handler_registration_free(reginfo); already freed */
            SNMP_FREE(vp);
        }
    }
    return SNMPERR_SUCCESS;
}

/** registers a row within a mib table */
int
netsnmp_register_mib_table_row(const char *moduleName,
                               struct variable *var,
                               size_t varsize,
                               size_t numvars,
                               oid * mibloc,
                               size_t mibloclen,
                               int priority,
                               int var_subid,
                               netsnmp_session * ss,
                               const char *context, int timeout, int flags)
{
    unsigned int    i = 0, rc = 0;
    oid             ubound = 0;

    for (i = 0; i < numvars; i++) {
        struct variable *vr =
            (struct variable *) ((char *) var + (i * varsize));
        netsnmp_handler_registration *r;
        if ( var_subid > (int)mibloclen ) {
            break;    /* doesn't make sense */
        }
        r = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);

        if (r == NULL) {
            /*
             * Unregister whatever we have registered so far, and
             * return an error.  
             */
            rc = MIB_REGISTRATION_FAILED;
            break;
        }
        memset(r, 0, sizeof(netsnmp_handler_registration));

        r->handler = get_old_api_handler();
        r->handlerName = strdup(moduleName);

        if (r->handlerName == NULL) {
            netsnmp_handler_registration_free(r);
            break;
        }

        r->rootoid_len = mibloclen;
        r->rootoid = (oid *) malloc(r->rootoid_len * sizeof(oid));

        if (r->rootoid == NULL) {
            netsnmp_handler_registration_free(r);
            rc = MIB_REGISTRATION_FAILED;
            break;
        }
        memcpy(r->rootoid, mibloc, mibloclen * sizeof(oid));
        memcpy((u_char *) (r->rootoid + (var_subid - vr->namelen)), vr->name,
               vr->namelen * sizeof(oid));
        DEBUGMSGTL(("netsnmp_register_mib_table_row", "rootoid "));
        DEBUGMSGOID(("netsnmp_register_mib_table_row", r->rootoid,
                     r->rootoid_len));
        DEBUGMSG(("netsnmp_register_mib_table_row", "(%d)\n",
                     (var_subid - vr->namelen)));
        r->handler->myvoid = (void *) malloc(varsize);

        if (r->handler->myvoid == NULL) {
            netsnmp_handler_registration_free(r);
            rc = MIB_REGISTRATION_FAILED;
            break;
        }
        memcpy((char *) r->handler->myvoid, vr, varsize);

        r->contextName = (context) ? strdup(context) : NULL;

        if (context != NULL && r->contextName == NULL) {
            netsnmp_handler_registration_free(r);
            rc = MIB_REGISTRATION_FAILED;
            break;
        }

        r->priority = priority;
        r->range_subid = 0;     /* var_subid; */
        r->range_ubound = 0;    /* range_ubound; */
        r->timeout = timeout;
        r->modes = HANDLER_CAN_RWRITE;

        /*
         * Register this column and row  
         */
        if ((rc =
             netsnmp_register_handler_nocallback(r)) !=
            MIB_REGISTERED_OK) {
            DEBUGMSGTL(("netsnmp_register_mib_table_row",
                        "register failed %d\n", rc));
            netsnmp_handler_registration_free(r);
            break;
        }

        if (vr->namelen > 0) {
            if (vr->name[vr->namelen - 1] > ubound) {
                ubound = vr->name[vr->namelen - 1];
            }
        }
    }

    if (rc == MIB_REGISTERED_OK) {
        struct register_parameters reg_parms;

        reg_parms.name = mibloc;
        reg_parms.namelen = mibloclen;
        reg_parms.priority = priority;
        reg_parms.flags = (u_char) flags;
        reg_parms.range_subid = var_subid;
        reg_parms.range_ubound = ubound;
        reg_parms.timeout = timeout;
        reg_parms.contextName = context;
        rc = snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                                 SNMPD_CALLBACK_REGISTER_OID, &reg_parms);
    }

    return rc;
}

/** implements the old_api handler */
int
netsnmp_old_api_helper(netsnmp_mib_handler *handler,
                       netsnmp_handler_registration *reginfo,
                       netsnmp_agent_request_info *reqinfo,
                       netsnmp_request_info *requests)
{

#if MIB_CLIENTS_ARE_EVIL
    oid             save[MAX_OID_LEN];
    size_t          savelen = 0;
#endif
    struct variable compat_var, *cvp = &compat_var;
    int             exact = 1;
    int             status;

    struct variable *vp;
    WriteMethod    *write_method = NULL;
    size_t          len;
    u_char         *access = NULL;
    netsnmp_old_api_cache *cacheptr;
    netsnmp_agent_session *oldasp = NULL;
    oid             tmp_name[MAX_OID_LEN];
    size_t          tmp_len;

    vp = (struct variable *) handler->myvoid;

    /*
     * create old variable structure with right information 
     */
    memcpy(cvp->name, reginfo->rootoid,
           reginfo->rootoid_len * sizeof(oid));
    cvp->namelen = reginfo->rootoid_len;
    cvp->type = vp->type;
    cvp->magic = vp->magic;
    cvp->acl = vp->acl;
    cvp->findVar = vp->findVar;

    switch (reqinfo->mode) {
    case MODE_GETNEXT:
    case MODE_GETBULK:
        exact = 0;
    }

    for (; requests; requests = requests->next) {

#if MIB_CLIENTS_ARE_EVIL
        savelen = requests->requestvb->name_length;
        memcpy(save, requests->requestvb->name, savelen * sizeof(oid));
#endif

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
        case MODE_SET_RESERVE1:
            /*
             * Actually call the old mib-module function 
             */
            if (vp && vp->findVar) {
                memcpy(tmp_name, requests->requestvb->name,
                                 requests->requestvb->name_length*sizeof(oid));
                tmp_len = requests->requestvb->name_length;
                access = (*(vp->findVar)) (cvp, tmp_name, &tmp_len,
                                           exact, &len, &write_method);
                snmp_set_var_objid( requests->requestvb, tmp_name, tmp_len );
            }
            else
                access = NULL;

#ifdef WWW_FIX
            if (IS_DELEGATED(cvp->type)) {
                add_method = (AddVarMethod *) statP;
                requests->delayed = 1;
                have_delegated = 1;
                continue;       /* WWW: This may not get to the right place */
            }
#endif

            /*
             * WWW: end range checking 
             */
            if (access) {
                /*
                 * result returned 
                 */
                if (reqinfo->mode != MODE_SET_RESERVE1)
                    snmp_set_var_typed_value(requests->requestvb,
                                             cvp->type, access, len);
            } else {
                /*
                 * no result returned 
                 */
#if MIB_CLIENTS_ARE_EVIL
                if (access == NULL) {
                    if (netsnmp_oid_equals(requests->requestvb->name,
                                         requests->requestvb->name_length,
                                         save, savelen) != 0) {
                        DEBUGMSGTL(("old_api", "evil_client: %s\n",
                                    reginfo->handlerName));
                        memcpy(requests->requestvb->name, save,
                               savelen * sizeof(oid));
                        requests->requestvb->name_length = savelen;
                    }
                }
#endif
            }

            /*
             * AAA: fall through for everything that is a set (see BBB) 
             */
            if (reqinfo->mode != MODE_SET_RESERVE1)
                break;

            cacheptr = SNMP_MALLOC_TYPEDEF(netsnmp_old_api_cache);
            if (!cacheptr)
                return netsnmp_set_request_error(reqinfo, requests,
                                                 SNMP_ERR_RESOURCEUNAVAILABLE);
            cacheptr->data = access;
            cacheptr->write_method = write_method;
            write_method = NULL;
            netsnmp_request_add_list_data(requests,
                                          netsnmp_create_data_list
                                          (OLD_API_NAME, cacheptr, free));
            /*
             * BBB: fall through for everything that is a set (see AAA) 
             */

        default:
            /*
             * WWW: explicitly list the SET conditions 
             */
            /*
             * (the rest of the) SET contions 
             */
            cacheptr =
                (netsnmp_old_api_cache *)
                netsnmp_request_get_list_data(requests, OLD_API_NAME);

            if (cacheptr == NULL || cacheptr->write_method == NULL) {
                /*
                 * WWW: try to set ourselves if possible? 
                 */
                return netsnmp_set_request_error(reqinfo, requests,
                                                 SNMP_ERR_NOTWRITABLE);
            }

            oldasp = netsnmp_get_current_agent_session();
            set_current_agent_session(reqinfo->asp);
            status =
                (*(cacheptr->write_method)) (reqinfo->mode,
                                             requests->requestvb->val.
                                             string,
                                             requests->requestvb->type,
                                             requests->requestvb->val_len,
                                             cacheptr->data,
                                             requests->requestvb->name,
                                             requests->requestvb->
                                             name_length);
            set_current_agent_session(oldasp);

            if (status != SNMP_ERR_NOERROR) {
                netsnmp_set_request_error(reqinfo, requests, status);
            }

            /*
             * clean up is done by the automatic freeing of the
             * cache stored in the request. 
             */

            break;
        }
    }
    return SNMP_ERR_NOERROR;
}

/** @} */

/*
 * don't use this! 
 */
static netsnmp_agent_session *current_agent_session = NULL;
netsnmp_agent_session *
netsnmp_get_current_agent_session()
{
    return current_agent_session;
}

/*
 * don't use this! 
 */
void
set_current_agent_session(netsnmp_agent_session *asp)
{
    current_agent_session = asp;
}
