#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);

    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);

    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;
}
