#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 <time.h>

#include <picl.h>
#include </usr/platform/sun4u/include/sys/envctrl.h>

void netsnmp_sensor_arch_init( void ) {
    DEBUGMSGTL(("sensors:arch", "Initialise PICLd Sensors module\n"));
    picl_initialize();
}


/*
 * Handle a numeric-valued sensor
 */
static int
read_num_sensor( picl_nodehdl_t childh, char *propval, float *value )
{
    picl_nodehdl_t  sensorh;
    picl_propinfo_t sensor_info;
    picl_errno_t    error_code;

    union valu {
        char buf[PICL_PROPSIZE_MAX];
        uint32_t us4;
        uint16_t us2;
        int32_t is4;
        int16_t is2;
        float f;
    } val;

    /*
     *  Retrieve the specified sensor information and value
     */
    error_code = picl_get_propinfo_by_name(childh, propval, &sensor_info, &sensorh);
    if ( error_code != PICL_SUCCESS ) {
        DEBUGMSGTL(("sensors:arch:detail", "sensor info lookup failed (%d)\n",
                                            error_code));
        return( error_code );
    }

    error_code = picl_get_propval(sensorh, &val.buf, sensor_info.size);
    if ( error_code != PICL_SUCCESS ) {
        DEBUGMSGTL(("sensors:arch:detail", "sensor value lookup failed (%d)\n",
                                            error_code));
        return( error_code );
    }

    /*
     *  Check the validity (type and size) of this value
     */
    if ( sensor_info.type == PICL_PTYPE_FLOAT ) {
        *value = val.f;
    } else if ( sensor_info.type == PICL_PTYPE_UNSIGNED_INT ) {
        /* 16-bit or 32-bit unsigned integers */
        if ( sensor_info.size == 2 ) {
            *value = val.us2;
        } else if ( sensor_info.size == 4 ) { 
            *value = val.us4;
        } else {
            DEBUGMSGTL(("sensors:arch:detail", "unsigned integer (%d bit)\n",
                                                sensor_info.size * 8));
            return PICL_FAILURE;
        }
    } else if ( sensor_info.type == PICL_PTYPE_INT ) {
        /* 16-bit or 32-bit signed integers */
        if ( sensor_info.size == 2 ) {
            *value = val.is2;
        } else if ( sensor_info.size == 4 ) { 
            *value = val.is4;
        } else {
            DEBUGMSGTL(("sensors:arch:detail", "signed integer (%d bit)\n",
                                                sensor_info.size * 8));
            return PICL_FAILURE;
        }
    } else {
        DEBUGMSGTL(("sensors:arch:detail", "unrecognised type (%d)\n",
                                            sensor_info.type));
        return PICL_FAILURE;
    }

    return error_code;
}

static int
process_num_sensor( picl_nodehdl_t childh, char *propname, char *propval, int typ )
{
    netsnmp_sensor_info        *sp;
    float                       value;
    picl_errno_t    error_code;

    sp = sensor_by_name( propname, typ );
    if ( !sp ) {
         return -1;
    }

    error_code = read_num_sensor( childh, propval, &value );
    if ( error_code == PICL_SUCCESS ) {
        sp->value = value;
        sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE;
    } else {
        DEBUGMSGTL(("sensors:arch:detail", "Failed to read %s sensor value (%d)\n",
                                            propname, error_code));
        return -1;
    }
    return 0;
}



/*
 *    Handle an enumeration-valued sensor
 */
char *switch_settings[] = { "OFF","ON","NORMAL","LOCKED",
                            "UNKNOWN","DIAG","SECURE",
                            NULL };
char *led_settings[]    = { "OFF","ON","BLINK",
                            NULL };
char *i2c_settings[]    = { "OK",
                            NULL };

static int
read_enum_sensor( picl_nodehdl_t childh, float *value, char **options )
{
    picl_nodehdl_t  sensorh;
    picl_propinfo_t sensor_info;
    picl_errno_t    error_code;
    char            state[PICL_PROPSIZE_MAX];
    int             i;

    /*
     *  Retrieve the specified sensor information and value
     */
    error_code = picl_get_propinfo_by_name(childh, "State", &sensor_info, &sensorh);
    if ( error_code != PICL_SUCCESS ) {
        DEBUGMSGTL(("sensors:arch:detail", "sensor info lookup failed (%d)\n",
                                            error_code));
        return( error_code );
    }

    error_code = picl_get_propval(sensorh, state, sensor_info.size);
    if ( error_code != PICL_SUCCESS ) {
        DEBUGMSGTL(("sensors:arch:detail", "sensor value lookup failed (%d)\n",
                                            error_code));
        return( error_code );
    }

    /*
     * Try to find a matching entry in the list of options.
     * Note that some platforms may use upper or lower case
     *   versions of these enumeration values
     *  (so the checks are case insensitive)
     */
    *value = 99;    /* Dummy value */
    for ( i=0;  options[i] != NULL; i++ ) {
        if (strncasecmp(state, options[i], strlen(options[i])) == 0) {
            *value = i;
            return 0;
        }
    }
    
    DEBUGMSGTL(("sensors:arch:detail", "Enumeration state %s not matched\n",
                                        state));
    return 0;  /* Or an error ? */
}

static int
process_enum_sensor( picl_nodehdl_t childh, char *propname, int typ, char **options )
{
    netsnmp_sensor_info        *sp;
    float                       value;
    picl_errno_t    error_code;

    sp = sensor_by_name( propname, typ );
    if ( !sp ) {
         return -1;
    }

    error_code = read_enum_sensor( childh, &value, options );
    if ( error_code == PICL_SUCCESS ) {
        sp->value = value;
        sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE;
    } else {
        DEBUGMSGTL(("sensors:arch:detail", "Failed to read %s sensor value (%d)\n",
                                            propname, error_code));
        return -1;
    }
    return 0;
}
static int
process_enum_sensor( picl_nodehdl_t childh, char *propname, int typ, char **options )
{
    return 0;
}



/*
 *  Recursively walk through the tree of sensors
 */
static int
process_sensors( int level, picl_nodehdl_t nodeh ) {
    picl_nodehdl_t childh, nexth;
    char           propname[  PICL_PROPNAMELEN_MAX  ];
    char           propclass[ PICL_CLASSNAMELEN_MAX ];
    picl_errno_t   error_code;

    level++;
    DEBUGMSGTL(("sensors:arch:detail", "process_sensors - level %d\n", level));

    /* Look up the first child node at this level */
    error_code = pick_get_propval_by_name( nodeh, PICL_PROP_CHILD,
                                           &childh, sizeof(childh));
    if ( error_code != PICL_SUCCESS ) {
        DEBUGMSGTL(("sensors:arch:detail", "Failed to get first child node (%d)\n",
                                            error_code));
        return( error_code );
    }

    /* Step through the child nodes, retrieving the name and class of each one */
    while ( error_code == PICL_SUCCESS ) {
        error_code = pick_get_propval_by_name( childh, PICL_PROP_NAME,
                                               propname, sizeof(propname)-1);
        if ( error_code != PICL_SUCCESS ) {
            /* The Node With No Name */
            DEBUGMSGTL(("sensors:arch:detail", "get property name failed (%d)\n",
                                                error_code));
            return( error_code );
        }

        error_code = pick_get_propval_by_name( childh, PICL_PROP_CLASSNAME,
                                               propclass, sizeof(propclass)-1);
        if ( error_code != PICL_SUCCESS ) {
            /* The Classless Society */
            DEBUGMSGTL(("sensors:arch:detail", "get property class failed (%d)\n",
                                                error_code));
            return( error_code );
        }

        DEBUGMSGTL(("sensors:arch:detail", "Name: %s, Class %s\n",
                                            propname, propclass ));


        /*
         *  Three classes represent further groups of sensors, etc.
         *  Call 'process_sensors' recursively to handle this next level
         */
        if (( strstr( propclass, "picl"    )) ||
            ( strstr( propclass, "frutree" )) ||
            ( strstr( propclass, "obp"     ))) {
            process_sensors( level, childh );
        }
        /*
         *  Otherwise retrieve the value appropriately based on the
         *     class of the sensor.
         *
         *  We need to specify the name of the PICL property to retrieve
         *     for this class of sensor, and the Net-SNMP sensor type.
         */
        else if ( strstr( propclass, "fan-tachometer" )) {
            process_num_sensor( childh, propname, "AtoDSensorValue",
                                                   NETSNMP_SENSOR_TYPE_RPM );
        } else if ( strstr( propclass, "fan" )) {
            process_num_sensor( childh, propname, "Speed",
                                                   NETSNMP_SENSOR_TYPE_RPM );
        } else if ( strstr( propclass, "temperature-sensor" )) {
            process_num_sensor( childh, propname, "Temperature",
                                                   NETSNMP_SENSOR_TYPE_TEMPERATURE );
        } else if ( strstr( propclass, "voltage-sensor" )) {
            process_num_sensor( childh, propname, "Voltage",
                                          /* ?? */ NETSNMP_SENSOR_TYPE_VOLTAGE_DC );
        } else if ( strstr( propclass, "digital-sensor" )) {
            process_num_sensor( childh, propname, "AtoDSensorValue",
                                          /* ?? */ NETSNMP_SENSOR_TYPE_VOLTAGE_DC );
            /*
             * Enumeration-valued sensors use a fixed PICL property ("State"),
             *   but take a list of the values appropriate for that sensor,
             *   as well as the Net-SNMP sensor type.
             */
        } else if ( strstr( propclass, "switch" )) {
            process_enum_sensor( childh, propname, NETSNMP_SENSOR_TYPE_OTHER,
                                                   switch_settings );
        } else if ( strstr( propclass, "led" )) {
            process_enum_sensor( childh, propname, NETSNMP_SENSOR_TYPE_OTHER,
                                                   led_settings );
        } else if ( strstr( propclass, "i2c" )) {
            process_enum_sensor( childh, propname, NETSNMP_SENSOR_TYPE_BOOLEAN, /* ?? */
                                                   i2c_settings );
        } else {
            /* Skip other classes of sensor */
            DEBUGMSGTL(("sensors:arch:detail", "Skipping class %s\n", propclass ));
        }

        /*
         *  Move on to the next child node at the current level (if any)
         */
        error_code = pick_get_propval_by_name( childh, PICL_PROP_PEER,
                                               &nexth, sizeof(nexth));
        if ( error_code != PICL_SUCCESS ) {
            /* That's All Folks! */
            return (( error_code == PICL_PROPNOTFOUND )
                          ? PICL_SUCCESS : error_code );
        }
        childh = nexth;
    }
    
    return error_code;
}


int
netsnmp_sensor_arch_load(netsnmp_cache *cache, void *vp) {
    int               error_code;
    picl_nodehdl_t    rooth;

    DEBUGMSGTL(("sensors:arch", "Reload PICLd Sensors module\n"));

    error_code = picl_get_root(&rooth);
    if ( error_code != PICL_SUCCESS) {
        DEBUGMSGTL(("sensors:arch", "Couldn't get root node (error %d)\n", error_code));
        return 1;
    }

    error_code = process_sensors(0, rooth);
    if ( error_code != 255 )
        if ( error_code != 7 )  /* ignore PICL_PROPNOTFOUND error */
            DEBUGMSGTL(("sensors:arch", "Internal PICLd problem (error %d)\n", error_code));

    return 0;
}

void netsnmp_sensor_arch_shutdown( void ) {
    DEBUGMSGTL(("sensors:arch", "Shutdown PicLD Sensors module\n"));
    picl_shutdown();
}

