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

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

netsnmp_feature_require(ulong_instance)
netsnmp_feature_require(register_read_only_table_data)
netsnmp_feature_require(table_build_result)
netsnmp_feature_require(table_dataset)

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

#ifndef NETSNMP_NO_WRITE_SUPPORT
    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;
#endif /* NETSNMP_NO_WRITE_SUPPORT */
    }

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