#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/library/snmp_logging.h>
#include "agent/nsLogging.h"
#include "util_funcs.h"



/*
 * OID and columns for the logging table.
 */

#define  NSLOGGING_TYPE		3
#define  NSLOGGING_MAXLEVEL	4
#define  NSLOGGING_STATUS	5

oid nsLoggingTable_oid[]      = { 1, 3, 6, 1, 4, 1, 8072, 1, 7, 2, 1};


void
init_nsLogging(void)
{
    netsnmp_table_registration_info *table_info;
    netsnmp_iterator_info           *iinfo;

    /*
     * Register 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_INTEGER,
                                                 ASN_PRIV_IMPLIED_OCTET_STR, 0);
    table_info->min_column = NSLOGGING_TYPE;
    table_info->max_column = NSLOGGING_STATUS;


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


    /*
     * .... and register the table with the agent.
     */
    netsnmp_register_table_iterator(
        netsnmp_create_handler_registration(
            "tzLoggingTable", handle_nsLoggingTable,
            nsLoggingTable_oid, OID_LENGTH(nsLoggingTable_oid),
            HANDLER_CAN_RWRITE),
        iinfo);
}


/*
 * nsLoggingTable handling
 */

netsnmp_variable_list *
get_first_logging_entry(void **loop_context, void **data_context,
                      netsnmp_variable_list *index,
                      netsnmp_iterator_info *data)
{
    long temp;
    netsnmp_log_handler  *logh_head = get_logh_head();
    if ( !logh_head )
        return NULL;

    temp = logh_head->priority;
    snmp_set_var_value(index, (u_char*)&temp,
		                 sizeof(temp));
    if ( logh_head->token )
        snmp_set_var_value(index->next_variable, (const u_char*)logh_head->token,
		                                   strlen(logh_head->token));
    else
        snmp_set_var_value(index->next_variable, NULL, 0);
    *loop_context = (void*)logh_head;
    *data_context = (void*)logh_head;
    return index;
}

netsnmp_variable_list *
get_next_logging_entry(void **loop_context, void **data_context,
                      netsnmp_variable_list *index,
                      netsnmp_iterator_info *data)
{
    long temp;
    netsnmp_log_handler *logh = (netsnmp_log_handler *)*loop_context;
    logh = logh->next;

    if ( !logh )
        return NULL;

    temp = logh->priority;
    snmp_set_var_value(index, (u_char*)&temp,
		                 sizeof(temp));
    if ( logh->token )
        snmp_set_var_value(index->next_variable, (const u_char*)logh->token,
		                                   strlen(logh->token));
    else
        snmp_set_var_value(index->next_variable, NULL, 0);
    *loop_context = (void*)logh;
    *data_context = (void*)logh;
    return index;
}


int
handle_nsLoggingTable(netsnmp_mib_handler *handler,
                netsnmp_handler_registration *reginfo,
                netsnmp_agent_request_info *reqinfo,
                netsnmp_request_info *requests)
{
    long temp;
    netsnmp_request_info       *request     = NULL;
    netsnmp_table_request_info *table_info  = NULL;
    netsnmp_log_handler        *logh        = NULL;
    netsnmp_variable_list      *idx         = NULL;

    switch (reqinfo->mode) {

    case MODE_GET:
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_TYPE:
                if (!logh) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
		}
		temp = logh->type;
	        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char*)&temp,
                                            sizeof(temp));
	        break;

            case NSLOGGING_MAXLEVEL:
                if (!logh) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
		}
		temp = logh->pri_max;
	        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char*)&temp,
                                            sizeof(temp));
	        break;

            case NSLOGGING_STATUS:
                if (!logh) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
		}
		temp = (logh->type ?
	                   (logh->enabled ?
	                      RS_ACTIVE:
	                      RS_NOTINSERVICE) :
	                    RS_NOTREADY);
	        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char*)&temp, sizeof(temp));
	        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->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_TYPE:
                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;
                }
		/*
		 * It's OK to create a new logging entry
		 *  (either in one go, or built up using createAndWait)
		 *  but it's not possible to change the type of an entry
		 *  once it's been created.
		 */
                if (logh && logh->type) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE);
                    return SNMP_ERR_NOTWRITABLE;
		}
	        break;

            case NSLOGGING_MAXLEVEL:
                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 ||
                    *request->requestvb->val.integer > 7 ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
	        break;

            case NSLOGGING_STATUS:
                if ( request->requestvb->type != ASN_INTEGER ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
		switch ( *request->requestvb->val.integer ) {
                case RS_ACTIVE:
                case RS_NOTINSERVICE:
                    /*
		     * Can only work on existing rows
		     */
                    if (!logh) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        return SNMP_ERR_INCONSISTENTVALUE;
                    }
	            break;

                case RS_CREATEANDWAIT:
                case RS_CREATEANDGO:
                    /*
		     * Can only work with new rows
		     */
                    if (logh) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        return SNMP_ERR_INCONSISTENTVALUE;
                    }

                    /*
                     *  Normally, we'd create the row at a later stage
                     *   (probably during the RESERVE2 or ACTION passes)
                     *
                     *  But we need to check that the values are
                     *   consistent during the ACTION pass (which is the
                     *   latest that an error can be safely handled),
                     *   so the values all need to be set up before this
                     *      (i.e. during the RESERVE2 pass)
                     *  So the new row needs to be created before that
                     *   in order to have somewhere to put them.
                     *
                     *  That's why we're doing this here.
                     */
                    idx = table_info->indexes;
	            logh = netsnmp_register_loghandler(
				    /* not really, but we need a valid type */
				    NETSNMP_LOGHANDLER_STDOUT,
				    *idx->val.integer);
                    if (!logh) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_GENERR); /* ??? */
                        return SNMP_ERR_GENERR;
                    }
                    idx = idx->next_variable;
	            logh->type  = 0;
	            logh->token = strdup((char *) idx->val.string);
                    netsnmp_insert_iterator_context(request, (void*)logh);
	            break;

                case RS_DESTROY:
                    /*
		     * Can work with new or existing rows
		     */
                    break;

                case RS_NOTREADY:
		default:
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
                break;

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


    case MODE_SET_RESERVE2:
        for (request=requests; request; request=request->next) {
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_TYPE:
                /*
		 * If we're creating a row using createAndGo,
		 * we need to set the type early, so that we
		 * can validate it in the ACTION pass.
		 *
		 * Remember that we need to be able to reverse this
		 */
                if ( logh )
                    logh->type = *request->requestvb->val.integer;
	        break;
            /*
	     * Don't need to handle nsLogToken or nsLogStatus in this pass
	     */
	    }
	}
	break;

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

            switch (table_info->colnum) {
            case NSLOGGING_STATUS:
                /*
		 * This is where we can check the internal consistency
		 * of the request.  Basically, for a row to be marked
		 * 'active', then there needs to be a valid type value.
		 */
		switch ( *request->requestvb->val.integer ) {
                case RS_ACTIVE:
                case RS_CREATEANDGO:
                    if ( !logh || !logh->type ) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        return SNMP_ERR_INCONSISTENTVALUE;
		    }
	            break;
		}
	        break;
            /*
	     * Don't need to handle nsLogToken or nsLogType in this pass
	     */
	    }
	}
	break;

    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        /*
         * If any resources were allocated in either of the
         *  two RESERVE passes, they need to be released here,
         *  and any assignments (in RESERVE2) reversed.
         *
         * Nothing additional will have been done during ACTION
         *  so this same code can do for UNDO as well.
         */
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_TYPE:
                /*
		 * If we've been setting the type, and the request
		 * has failed, then revert to an unset type.
		 *
		 * We need to be careful here - if the reason it failed is
		 *  that the type was already set, then we shouldn't "undo"
		 *  the assignment (since it won't actually have been made).
		 *
		 * Check the current value against the 'new' one.  If they're
		 * the same, then this is probably a successful assignment,
		 * and the failure was elsewhere, so we need to undo it.
		 *  (Or else there was an attempt to write the same value!)
		 */
                if ( logh && logh->type == *request->requestvb->val.integer )
                    logh->type = 0;
	        break;

            case NSLOGGING_STATUS:
                temp = *request->requestvb->val.integer;
                if ( logh && ( temp == RS_CREATEANDGO ||
                               temp == RS_CREATEANDWAIT)) {
		    netsnmp_remove_loghandler( logh );
		}
	        break;
            /*
	     * Don't need to handle nsLogToken in this pass
	     */
	    }
	}
	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 */
            }
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            if (!logh) {
                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 NSLOGGING_MAXLEVEL:
                logh->pri_max = *request->requestvb->val.integer;
	        break;

            case NSLOGGING_STATUS:
                switch (*request->requestvb->val.integer) {
                    case RS_ACTIVE:
                    case RS_CREATEANDGO:
                        logh->enabled = 1;
                        break;
                    case RS_NOTINSERVICE:
                    case RS_CREATEANDWAIT:
                        logh->enabled = 0;
                        break;
		    case RS_DESTROY:
		        netsnmp_remove_loghandler( logh );
                        break;
		}
	        break;
	    }
	}
	break;
    }

    return SNMP_ERR_NOERROR;
}
