#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/hardware/sensors.h>
#include "hardware/sensors/hw_sensors.h"
#include "ucd-snmp/lmsensorsMib.h"

netsnmp_container *sensorContainer = NULL;

void initialize_lmSensorsTable(const char *tableName, const oid *tableOID,
                               netsnmp_container_op *filter, int mult );

int _sensor_filter_temp( netsnmp_container *c, const void *v );
int _sensor_filter_fan(  netsnmp_container *c, const void *v );
int _sensor_filter_volt( netsnmp_container *c, const void *v );
int _sensor_filter_misc( netsnmp_container *c, const void *v );

static const oid lmTempSensorsTable_oid[]   = {1,3,6,1,4,1,2021,13,16,2};
static const oid lmFanSensorsTable_oid[]    = {1,3,6,1,4,1,2021,13,16,3};
static const oid lmVoltSensorsTable_oid[]   = {1,3,6,1,4,1,2021,13,16,4};
static const oid lmMiscSensorsTable_oid[]   = {1,3,6,1,4,1,2021,13,16,5};
            /* All the tables have the same length root OID */
const size_t lmSensorsTables_oid_len = OID_LENGTH(lmMiscSensorsTable_oid);


/* Initialise the LM Sensors MIB module */
void
init_lmsensorsMib(void)
{
    DEBUGMSGTL(("ucd-snmp/lmsensorsMib","Initializing LM-SENSORS-MIB tables\n"));

    /* 
     * Initialise the four LM-SENSORS-MIB tables
     *
     * They are almost identical, so we can use the same registration code.
     */
    initialize_lmSensorsTable( "lmTempSensorsTable", lmTempSensorsTable_oid,
                                _sensor_filter_temp, 1000 );  /* MIB asks for mC */
    initialize_lmSensorsTable( "lmFanSensorsTable",  lmFanSensorsTable_oid,
                                _sensor_filter_fan,  1);
    initialize_lmSensorsTable( "lmVoltSensorsTable", lmVoltSensorsTable_oid,
                                _sensor_filter_volt, 1000 );  /* MIB asks for mV */
    initialize_lmSensorsTable( "lmMiscSensorsTable", lmMiscSensorsTable_oid,
                                _sensor_filter_misc, 1 );
}

/*
 * Common initialisation code, used for setting up all four tables
 */
void
initialize_lmSensorsTable(const char *tableName, const oid *tableOID,
                          netsnmp_container_op *filter, int mult )
{
    netsnmp_handler_registration    *reg;
    netsnmp_table_registration_info *table_info;
    netsnmp_cache     *cache;
    netsnmp_container *container;

    /*
     * Ensure the HAL sensors module has been initialised,
     *   and retrieve the main sensors container.
     * This table will then be registered using a filter on this container.
     */
    sensorContainer = get_sensor_container();
    if ( !sensorContainer ) {
        init_hw_sensors( );
        sensorContainer = get_sensor_container();
    }
    container = netsnmp_container_find("sensorTable:table_container");
    container->insert_filter = filter;
    netsnmp_container_add_index( sensorContainer, container );


    /*
     * Create a basic registration structure for the table
     */
    reg = netsnmp_create_handler_registration(
               tableName, lmSensorsTables_handler,
               tableOID,  lmSensorsTables_oid_len, HANDLER_CAN_RONLY
              );

    /*
     * Register the table using the filtered container
     * Include an indicator of any scaling to be applied to the sensor value
     */
    reg->my_reg_void = (void *)(uintptr_t)mult;
    table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0);
    table_info->min_column = COLUMN_LMSENSORS_INDEX;
    table_info->max_column = COLUMN_LMSENSORS_VALUE;
    netsnmp_container_table_register( reg, table_info, container, 0 );

    /*
     * If the HAL sensors module was configured as an on-demand caching
     *  module (rather than being automatically loaded regularly),
     *  then ensure this table makes use of that cache.
     */
    cache = get_sensor_cache();
    if ( cache ) {
        netsnmp_inject_handler_before( reg, netsnmp_cache_handler_get( cache ),
                                            "table_container");
    }

}


/*
 *  Container filters for the four tables
 *
 *  Used to ensure that sensor entries appear in the appropriate table.
 */
int _sensor_filter_temp( netsnmp_container *c, const void *v ) {
    const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v;
    /* Only matches temperature sensors */
    return (( sp->type == NETSNMP_SENSOR_TYPE_TEMPERATURE ) ? 0 : 1 );
}

int _sensor_filter_fan( netsnmp_container *c, const void *v ) {
    const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v;
    /* Only matches fan sensors */
    return (( sp->type == NETSNMP_SENSOR_TYPE_RPM ) ? 0 : 1 );
}

int _sensor_filter_volt( netsnmp_container *c, const void *v ) {
    const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v;
    /* Only matches voltage sensors (AC or DC) */
    return ((( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_DC ) ||
             ( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_AC )) ? 0 : 1 );
}

int _sensor_filter_misc( netsnmp_container *c, const void *v ) {
    const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v;
    /* Matches everything except temperature, fan or voltage sensors */
    return ((( sp->type == NETSNMP_SENSOR_TYPE_TEMPERATURE ) ||
             ( sp->type == NETSNMP_SENSOR_TYPE_RPM         ) ||
             ( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_DC  ) ||
             ( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_AC  )) ? 1 : 0 );
}


/*
 * Handle requests for any of the four lmXxxxSensorsTables 
 *
 * This is possible because all the table share the
 *  same structure and behaviour.
 */
int
lmSensorsTables_handler(
    netsnmp_mib_handler               *handler,
    netsnmp_handler_registration      *reginfo,
    netsnmp_agent_request_info        *reqinfo,
    netsnmp_request_info              *requests) {

    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_info;
    netsnmp_sensor_info        *sensor_info;
    int mult  = (uintptr_t)reginfo->my_reg_void;

    DEBUGMSGTL(( "ucd-snmp/lmsensorsMib","lmSensorsTables_handler - root: "));
    DEBUGMSGOID(("ucd-snmp/lmsensorsMib", reginfo->rootoid, reginfo->rootoid_len));
    DEBUGMSG((   "ucd-snmp/lmsensorsMib",", mode %d\n", reqinfo->mode ));
    /*
     * This is a read-only table, so we only need to handle GET requests.
     *    (The container helper converts GETNEXT->GET requests automatically).
     */
    switch (reqinfo->mode) {
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            sensor_info = (netsnmp_sensor_info *)
                            netsnmp_container_table_extract_context(request);
            if ( !sensor_info ) {
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                continue;
            }
    
            table_info   =  netsnmp_extract_table_info(request);
            switch (table_info->colnum) {
            case COLUMN_LMSENSORS_INDEX:
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            sensor_info->idx.oids[0]);
                break;
            case COLUMN_LMSENSORS_DEVICE:
                if ( sensor_info->descr[0] != '\0' ) {
                    snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
                                              sensor_info->descr, strlen(sensor_info->descr));
                } else {
                    snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
                                              sensor_info->name,  strlen(sensor_info->name));
                }
                break;
            case COLUMN_LMSENSORS_VALUE:
                /* Multiply the value by the appropriate scaling factor for this table */
                snmp_set_var_typed_integer( request->requestvb, ASN_GAUGE,
                                            (int)(mult*sensor_info->value));
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            }
        }
        break;

    }
    return SNMP_ERR_NOERROR;
}
