#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/scalar.h>

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

#include <net-snmp/agent/cache_handler.h>
#include "agent/nsCache.h"

/*
 * use unadvertised function to get cache head. You really should not
 * do this, since the internal storage mechanism might change.
 */
extern netsnmp_cache *netsnmp_cache_get_head(void);


#define nsCache 1, 3, 6, 1, 4, 1, 8072, 1, 5

/*
 * OIDs for the cacheging control scalar objects
 *
 * Note that these we're registering the full object rather
 *  than the (sole) valid instance in each case, in order
 *  to handle requests for invalid instances properly.
 */

/*
 * ... and for the cache table.
 */

#define  NSCACHE_TIMEOUT	2
#define  NSCACHE_STATUS		3

#define NSCACHE_STATUS_ENABLED  1
#define NSCACHE_STATUS_DISABLED 2
#define NSCACHE_STATUS_EMPTY    3
#define NSCACHE_STATUS_ACTIVE   4
#define NSCACHE_STATUS_EXPIRED  5

NETSNMP_IMPORT struct snmp_alarm *
sa_find_specific(unsigned int clientreg);


void
init_nsCache(void)
{
    const oid nsCacheTimeout_oid[]    = { nsCache, 1 };
    const oid nsCacheEnabled_oid[]    = { nsCache, 2 };
    const oid nsCacheTable_oid[]      = { nsCache, 3 };

    netsnmp_table_registration_info *table_info;
    netsnmp_iterator_info           *iinfo;

    /*
     * Register the scalar objects...
     */
    DEBUGMSGTL(("nsCacheScalars", "Initializing\n"));
    netsnmp_register_scalar(
        netsnmp_create_handler_registration(
            "nsCacheTimeout", handle_nsCacheTimeout,
            nsCacheTimeout_oid, OID_LENGTH(nsCacheTimeout_oid),
            HANDLER_CAN_RWRITE)
        );
    netsnmp_register_scalar(
        netsnmp_create_handler_registration(
            "nsCacheEnabled", handle_nsCacheEnabled,
            nsCacheEnabled_oid, OID_LENGTH(nsCacheEnabled_oid),
            HANDLER_CAN_RWRITE)
        );

    /*
     * ... and the table.
     * We need to define the column structure and indexing....
     */

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (!table_info) {
        return;
    }
    netsnmp_table_helper_add_indexes(table_info, ASN_PRIV_IMPLIED_OBJECT_ID, 0);
    table_info->min_column = NSCACHE_TIMEOUT;
    table_info->max_column = NSCACHE_STATUS;


    /*
     * .... and the iteration information ....
     */
    iinfo      = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
    if (!iinfo) {
        return;
    }
    iinfo->get_first_data_point = get_first_cache_entry;
    iinfo->get_next_data_point  = get_next_cache_entry;
    iinfo->table_reginfo        = table_info;


    /*
     * .... and register the table with the agent.
     */
    netsnmp_register_table_iterator(
        netsnmp_create_handler_registration(
            "tzCacheTable", handle_nsCacheTable,
            nsCacheTable_oid, OID_LENGTH(nsCacheTable_oid),
            HANDLER_CAN_RWRITE),
        iinfo);
}


/*
 * nsCache scalar handling
 */

int
handle_nsCacheTimeout(netsnmp_mib_handler *handler,
                netsnmp_handler_registration *reginfo,
                netsnmp_agent_request_info *reqinfo,
                netsnmp_request_info *requests)
{
    long cache_default_timeout =
        netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_CACHE_TIMEOUT);
    netsnmp_request_info *request=NULL;

    switch (reqinfo->mode) {

    case MODE_GET:
	for (request = requests; request; request=request->next) {
	    snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                     (u_char*)&cache_default_timeout,
                                        sizeof(cache_default_timeout));
	}
	break;


    case MODE_SET_RESERVE1:
	for (request = requests; request; request=request->next) {
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            if ( request->requestvb->type != ASN_INTEGER ) {
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
                return SNMP_ERR_WRONGTYPE;
            }
            if ( *request->requestvb->val.integer < 0 ) {
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
                return SNMP_ERR_WRONGVALUE;
            }
        }
        break;

    case MODE_SET_COMMIT:
        netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_CACHE_TIMEOUT,
                           *requests->requestvb->val.integer);
        break;
    }

    return SNMP_ERR_NOERROR;
}


int
handle_nsCacheEnabled(netsnmp_mib_handler *handler,
                netsnmp_handler_registration *reginfo,
                netsnmp_agent_request_info *reqinfo,
                netsnmp_request_info *requests)
{
    long enabled;
    netsnmp_request_info *request=NULL;

    switch (reqinfo->mode) {

    case MODE_GET:
	enabled =  (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                           NETSNMP_DS_AGENT_NO_CACHING)
                       ? NSCACHE_STATUS_ENABLED    /* Actually True/False */
                       : NSCACHE_STATUS_DISABLED );
	for (request = requests; request; request=request->next) {
	    snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                     (u_char*)&enabled, sizeof(enabled));
	}
	break;


    case MODE_SET_RESERVE1:
	for (request = requests; request; request=request->next) {
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            if ( request->requestvb->type != ASN_INTEGER ) {
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
                return SNMP_ERR_WRONGTYPE;
            }
            if ((*request->requestvb->val.integer != NSCACHE_STATUS_ENABLED) &&
                (*request->requestvb->val.integer != NSCACHE_STATUS_DISABLED)) {
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
                return SNMP_ERR_WRONGVALUE;
            }
        }
        break;

    case MODE_SET_COMMIT:
        enabled = *requests->requestvb->val.integer;
	if (enabled == NSCACHE_STATUS_DISABLED)
	    enabled = 0;
	netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_NO_CACHING, enabled);
        break;
    }

    return SNMP_ERR_NOERROR;
}


/*
 * nsCacheTable handling
 */

netsnmp_variable_list *
get_first_cache_entry(void **loop_context, void **data_context,
                      netsnmp_variable_list *index,
                      netsnmp_iterator_info *data)
{
    netsnmp_cache  *cache_head = netsnmp_cache_get_head();

    if ( !cache_head )
        return NULL;

    snmp_set_var_value(index, (u_char*)cache_head->rootoid,
		         sizeof(oid) * cache_head->rootoid_len);
    *loop_context = (void*)cache_head;
    *data_context = (void*)cache_head;
    return index;
}

netsnmp_variable_list *
get_next_cache_entry(void **loop_context, void **data_context,
                      netsnmp_variable_list *index,
                      netsnmp_iterator_info *data)
{
    netsnmp_cache *cache = (netsnmp_cache *)*loop_context;
    cache = cache->next;

    if ( !cache )
        return NULL;

    snmp_set_var_value(index, (u_char*)cache->rootoid,
		         sizeof(oid) * cache->rootoid_len);
    *loop_context = (void*)cache;
    *data_context = (void*)cache;
    return index;
}


int
handle_nsCacheTable(netsnmp_mib_handler *handler,
                netsnmp_handler_registration *reginfo,
                netsnmp_agent_request_info *reqinfo,
                netsnmp_request_info *requests)
{
    long status;
    netsnmp_request_info       *request     = NULL;
    netsnmp_table_request_info *table_info  = NULL;
    netsnmp_cache              *cache_entry = NULL;

    switch (reqinfo->mode) {

    case MODE_GET:
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;

            cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSCACHE_TIMEOUT:
                if (!cache_entry) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
		}
		status = cache_entry->timeout;
	        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char*)&status, sizeof(status));
	        break;

            case NSCACHE_STATUS:
                if (!cache_entry) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
		}
		status = (cache_entry->enabled ?
	                   (cache_entry->timestamp ?
                             (!atime_ready(cache_entry->timestamp,
                                          1000*cache_entry->timeout) ?
	                        NSCACHE_STATUS_ACTIVE:
	                        NSCACHE_STATUS_EXPIRED) :
	                      NSCACHE_STATUS_EMPTY) :
	                    NSCACHE_STATUS_DISABLED);
	        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char*)&status, sizeof(status));
	        break;

            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                continue;
	    }
	}
	break;


    case MODE_SET_RESERVE1:
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSCACHE_TIMEOUT:
                if (!cache_entry) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
                    return SNMP_ERR_NOCREATION;
		}
                if ( request->requestvb->type != ASN_INTEGER ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                if (*request->requestvb->val.integer < 0 ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
	        break;

            case NSCACHE_STATUS:
                if (!cache_entry) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
                    return SNMP_ERR_NOCREATION;
		}
                if ( request->requestvb->type != ASN_INTEGER ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                status = *request->requestvb->val.integer;
                if (!((status == NSCACHE_STATUS_ENABLED  ) ||
                      (status == NSCACHE_STATUS_DISABLED ) ||
                      (status == NSCACHE_STATUS_EMPTY  ))) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
	        break;

            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
                return SNMP_ERR_NOCREATION;	/* XXX - is this right ? */
	    }
	}
	break;


    case MODE_SET_COMMIT:
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
            if (!cache_entry) {
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_COMMITFAILED);
                return SNMP_ERR_COMMITFAILED;	/* Shouldn't happen! */
            }
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSCACHE_TIMEOUT:
                cache_entry->timeout = *request->requestvb->val.integer;
                /*
                 * check for auto repeat
                 */
                if (cache_entry->timer_id) {
                    struct snmp_alarm * sa =
                        sa_find_specific(cache_entry->timer_id);
                    if (NULL != sa)
                        sa->t.tv_sec = cache_entry->timeout;
                }
	        break;

            case NSCACHE_STATUS:
                switch (*request->requestvb->val.integer) {
                    case NSCACHE_STATUS_ENABLED:
                        cache_entry->enabled = 1;
                        break;
		    case NSCACHE_STATUS_DISABLED:
                        cache_entry->enabled = 0;
                        break;
		    case NSCACHE_STATUS_EMPTY:
                        cache_entry->free_cache(cache_entry, cache_entry->magic);
                        free(cache_entry->timestamp);
                        cache_entry->timestamp = NULL;
                        break;
		}
	        break;
	    }
	}
	break;
    }

    return SNMP_ERR_NOERROR;
}
