#include <net-snmp/net-snmp-config.h>

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#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 "testhandler.h"

#include <net-snmp/agent/table.h>
#include <net-snmp/agent/instance.h>
#include <net-snmp/agent/table_data.h>
#include <net-snmp/agent/table_dataset.h>

static oid      my_test_oid[4] = { 1, 2, 3, 4 };
static oid      my_table_oid[4] = { 1, 2, 3, 5 };
static oid      my_instance_oid[5] = { 1, 2, 3, 6, 1 };
static oid      my_data_table_oid[4] = { 1, 2, 3, 7 };
static oid      my_data_table_set_oid[4] = { 1, 2, 3, 8 };
static oid      my_data_ulong_instance[4] = { 1, 2, 3, 9 };

u_long          my_ulong = 0;

void
init_testhandler(void)
{
    /*
     * we're registering at .1.2.3.4 
     */
    netsnmp_handler_registration *my_test;
    netsnmp_table_registration_info *table_info;
    u_long          ind1;
    netsnmp_table_data *table;
    netsnmp_table_data_set *table_set;
    netsnmp_table_row *row;

    DEBUGMSGTL(("testhandler", "initializing\n"));

    /*
     * basic handler test
     */
    netsnmp_register_handler(netsnmp_create_handler_registration
                             ("myTest", my_test_handler, my_test_oid, 4,
                              HANDLER_CAN_RONLY));

    /*
     * instance handler test
     */

    netsnmp_register_instance(netsnmp_create_handler_registration
                              ("myInstance", my_test_instance_handler,
                               my_instance_oid, 5, HANDLER_CAN_RWRITE));

    netsnmp_register_ulong_instance("myulong",
                                    my_data_ulong_instance, 4,
                                    &my_ulong, NULL);

    /*
     * table helper test
     */

    my_test = netsnmp_create_handler_registration("myTable",
                                                  my_test_table_handler,
                                                  my_table_oid, 4,
                                                  HANDLER_CAN_RONLY);
    if (!my_test)
        return;

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (table_info == NULL)
        return;

    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, ASN_INTEGER,
                                     0);
    table_info->min_column = 3;
    table_info->max_column = 3;
    netsnmp_register_table(my_test, table_info);

    /*
     * data table helper test
     */
    /*
     * we'll construct a simple table here with two indexes: an
     * integer and a string (why not).  It'll contain only one
     * column so the data pointer is merely the data in that
     * column. 
     */

    table = netsnmp_create_table_data("data_table_test");

    netsnmp_table_data_add_index(table, ASN_INTEGER);
    netsnmp_table_data_add_index(table, ASN_OCTET_STR);

    /*
     * 1 partridge in a pear tree 
     */
    row = netsnmp_create_table_data_row();
    ind1 = 1;
    netsnmp_table_row_add_index(row, ASN_INTEGER, &ind1, sizeof(ind1));
    netsnmp_table_row_add_index(row, ASN_OCTET_STR, "partridge",
                                strlen("partridge"));
    row->data = (void *) "pear tree";
    netsnmp_table_data_add_row(table, row);

    /*
     * 2 turtle doves 
     */
    row = netsnmp_create_table_data_row();
    ind1 = 2;
    netsnmp_table_row_add_index(row, ASN_INTEGER, &ind1, sizeof(ind1));
    netsnmp_table_row_add_index(row, ASN_OCTET_STR, "turtle",
                                strlen("turtle"));
    row->data = (void *) "doves";
    netsnmp_table_data_add_row(table, row);

    /*
     * we're going to register it as a normal table too, so we get the
     * automatically parsed column and index information 
     */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (table_info == NULL)
        return;

    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,
                                     ASN_OCTET_STR, 0);
    table_info->min_column = 3;
    table_info->max_column = 3;

    netsnmp_register_read_only_table_data
        (netsnmp_create_handler_registration
         ("12days", my_data_table_handler, my_data_table_oid, 4,
          HANDLER_CAN_RONLY), table, table_info);

}

int
my_test_handler(netsnmp_mib_handler *handler,
                netsnmp_handler_registration *reginfo,
                netsnmp_agent_request_info *reqinfo,
                netsnmp_request_info *requests)
{

    oid             myoid1[] = { 1, 2, 3, 4, 5, 6 };
    static u_long   accesses = 0;

    DEBUGMSGTL(("testhandler", "Got request:\n"));
    /*
     * loop through requests 
     */
    while (requests) {
        netsnmp_variable_list *var = requests->requestvb;

        DEBUGMSGTL(("testhandler", "  oid:"));
        DEBUGMSGOID(("testhandler", var->name, var->name_length));
        DEBUGMSG(("testhandler", "\n"));

        switch (reqinfo->mode) {
        case MODE_GET:
            if (netsnmp_oid_equals(var->name, var->name_length, myoid1, 6)
                == 0) {
                snmp_set_var_typed_value(var, ASN_INTEGER,
                                         (u_char *) & accesses,
                                         sizeof(accesses));
                return SNMP_ERR_NOERROR;
            }
            break;

        case MODE_GETNEXT:
            if (snmp_oid_compare(var->name, var->name_length, myoid1, 6)
                < 0) {
                snmp_set_var_objid(var, myoid1, 6);
                snmp_set_var_typed_value(var, ASN_INTEGER,
                                         (u_char *) & accesses,
                                         sizeof(accesses));
                return SNMP_ERR_NOERROR;
            }
            break;

        default:
            netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
            break;
        }

        requests = requests->next;
    }
    return SNMP_ERR_NOERROR;
}

/*
 * functionally this is a simply a multiplication table for 12x12
 */

#define MAX_COLONE 12
#define MAX_COLTWO 12
#define RESULT_COLUMN 3
int
my_test_table_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests)
{

    netsnmp_table_registration_info
        *handler_reg_info =
        (netsnmp_table_registration_info *) handler->prev->myvoid;

    netsnmp_table_request_info *table_info;
    u_long          result;
    int             x, y;

    while (requests) {
        netsnmp_variable_list *var = requests->requestvb;

        if (requests->processed != 0)
            continue;

        DEBUGMSGTL(("testhandler_table", "Got request:\n"));
        DEBUGMSGTL(("testhandler_table", "  oid:"));
        DEBUGMSGOID(("testhandler_table", var->name, var->name_length));
        DEBUGMSG(("testhandler_table", "\n"));

        table_info = netsnmp_extract_table_info(requests);
        if (table_info == NULL) {
            requests = requests->next;
            continue;
        }

        switch (reqinfo->mode) {
        case MODE_GETNEXT:
            /*
             * beyond our search range? 
             */
            if (table_info->colnum > RESULT_COLUMN)
                break;

            /*
             * below our minimum column? 
             */
            if (table_info->colnum < RESULT_COLUMN ||
                /*
                 * or no index specified 
                 */
                table_info->indexes->val.integer == 0) {
                table_info->colnum = RESULT_COLUMN;
                x = 0;
                y = 0;
            } else {
                x = *(table_info->indexes->val.integer);
                y = *(table_info->indexes->next_variable->val.integer);
            }

            if (table_info->number_indexes ==
                handler_reg_info->number_indexes) {
                y++;            /* GETNEXT is basically just y+1 for this table */
                if (y > MAX_COLTWO) {   /* (with wrapping) */
                    y = 0;
                    x++;
                }
            }
            if (x <= MAX_COLONE) {
                result = x * y;

                *(table_info->indexes->val.integer) = x;
                *(table_info->indexes->next_variable->val.integer) = y;
                netsnmp_table_build_result(reginfo, requests,
                                           table_info, ASN_INTEGER,
                                           (u_char *) & result,
                                           sizeof(result));
            }

            break;

        case MODE_GET:
            if (var->type == ASN_NULL) {        /* valid request if ASN_NULL */
                /*
                 * is it the right column? 
                 */
                if (table_info->colnum == RESULT_COLUMN &&
                    /*
                     * and within the max boundries? 
                     */
                    *(table_info->indexes->val.integer) <= MAX_COLONE &&
                    *(table_info->indexes->next_variable->val.integer)
                    <= MAX_COLTWO) {

                    /*
                     * then, the result is column1 * column2 
                     */
                    result = *(table_info->indexes->val.integer) *
                        *(table_info->indexes->next_variable->val.integer);
                    snmp_set_var_typed_value(var, ASN_INTEGER,
                                             (u_char *) & result,
                                             sizeof(result));
                }
            }
            break;

        }

        requests = requests->next;
    }

    return SNMP_ERR_NOERROR;
}

#define TESTHANDLER_SET_NAME "my_test"
int
my_test_instance_handler(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *reqinfo,
                         netsnmp_request_info *requests)
{

    static u_long   accesses = 0;
    u_long         *accesses_cache = NULL;

    DEBUGMSGTL(("testhandler", "Got instance request:\n"));

    switch (reqinfo->mode) {
    case MODE_GET:
        snmp_set_var_typed_value(requests->requestvb, ASN_UNSIGNED,
                                 (u_char *) & accesses, sizeof(accesses));
        break;

    case MODE_SET_RESERVE1:
        if (requests->requestvb->type != ASN_UNSIGNED)
            netsnmp_set_request_error(reqinfo, requests,
                                      SNMP_ERR_WRONGTYPE);
        break;

    case MODE_SET_RESERVE2:
        /*
         * store old info for undo later 
         */
        accesses_cache = netsnmp_memdup(&accesses, sizeof(accesses));
        if (accesses_cache == NULL) {
            netsnmp_set_request_error(reqinfo, requests,
                                      SNMP_ERR_RESOURCEUNAVAILABLE);
            return SNMP_ERR_NOERROR;
        }
        netsnmp_request_add_list_data(requests,
                                      netsnmp_create_data_list
                                      (TESTHANDLER_SET_NAME,
                                       accesses_cache, free));
        break;

    case MODE_SET_ACTION:
        /*
         * update current 
         */
        accesses = *(requests->requestvb->val.integer);
        DEBUGMSGTL(("testhandler", "updated accesses -> %d\n", accesses));
        break;

    case MODE_SET_UNDO:
        accesses =
            *((u_long *) netsnmp_request_get_list_data(requests,
                                                       TESTHANDLER_SET_NAME));
        break;

    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
        /*
         * nothing to do 
         */
        break;
    }

    return SNMP_ERR_NOERROR;
}

int
my_data_table_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests)
{

    char           *column3;
    netsnmp_table_request_info *table_info;
    netsnmp_table_row *row;

    while (requests) {
        if (requests->processed) {
            requests = requests->next;
            continue;
        }

        /*
         * extract our stored data and table info 
         */
        row = netsnmp_extract_table_row(requests);
        table_info = netsnmp_extract_table_info(requests);
        if (row)
            column3 = (char *) row->data;
        if (!row || !table_info || !column3)
            continue;

        /*
         * there's only one column, we don't need to check if it's right 
         */
        netsnmp_table_data_build_result(reginfo, reqinfo, requests, row,
                                        table_info->colnum,
                                        ASN_OCTET_STR, column3,
                                        strlen(column3));
        requests = requests->next;
    }
    return SNMP_ERR_NOERROR;
}
