#include <stdio.h>
#include <string.h>
#include <stdint.h>


extern unsigned char findSensor(char);
extern int set_sensor_dbus_state_v(uint8_t , const char *, char *);


struct sensorRES_t {
	uint8_t sensor_number;
	uint8_t operation;
	uint8_t sensor_reading;
	uint8_t assert_state7_0;
	uint8_t assert_state14_8;	
	uint8_t deassert_state7_0;
	uint8_t deassert_state14_8;	
	uint8_t event_data1;
	uint8_t event_data2;
	uint8_t event_data3;	
} __attribute__ ((packed));

#define ISBITSET(x,y) (((x)>>(y))&0x01)
#define ASSERTINDEX 0
#define DEASSERTINDEX 1

// Sensor Type,  Offset, function handler, Dbus Method, Assert value, Deassert value
struct lookup_t {
	uint8_t sensor_type;
	uint8_t offset;
	int (*func)(const sensorRES_t *, const lookup_t *, const char *);
	char    method[16];
	char    assertion[16];
	char    deassertion[16];
};


extern int updateDbusInterface(uint8_t , const char *, const char *) ;
extern int set_sensor_dbus_state(uint8_t ,const char *, const char *);


int set_sensor_dbus_state_simple(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {

	return set_sensor_dbus_state(pRec->sensor_number, pTable->method, value);
}

struct event_data_t {
	uint8_t data;
	char    text[32];
};

event_data_t g_fwprogress02h[] = {
	{0x00, "Unspecified"},
	{0x01, "Memory Init"},
	{0x02, "HD Init"},
	{0x03, "Secondary Proc Init"},
	{0x04, "User Authentication"},
	{0x05, "User init system setup"},
	{0x06, "USB configuration"},
	{0x07, "PCI configuration"},
	{0x08, "Option ROM Init"},
	{0x09, "Video Init"},
	{0x0A, "Cache Init"},
	{0x0B, "SM Bus init"},
	{0x0C, "Keyboard Init"},
	{0x0D, "Embedded ctrl init"},
	{0x0E, "Docking station attachment"},
	{0x0F, "Enable docking station"},
	{0x10, "Docking station ejection"},
	{0x11, "Disabling docking station"},
	{0x12, "Calling OS Wakeup"},
	{0x13, "Starting OS"},
	{0x14, "Baseboard Init"},
	{0x15, ""},
	{0x16, "Floppy Init"},
	{0x17, "Keyboard Test"},
	{0x18, "Pointing Device Test"},
	{0x19, "Primary Proc Init"},
	{0xFF, "Unknown"}
};


char *getfw02string(uint8_t b) {

	int i = 0;
	event_data_t *p = g_fwprogress02h;

	do {

		if ((p+i)->data == b)
			break;
		i++;
	} while ((p+i)->data != 0xFF);

	return (p+i)->text;
}
//  The fw progress sensor contains some additional information that needs to be processed
//  prior to calling the dbus code.  
int set_sensor_dbus_state_fwprogress(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {

	char valuestring[32];
	char* pStr = valuestring;

	switch (pTable->offset) {

		case 0x00 : sprintf(valuestring, "POST Error, 0x%02x", pRec->event_data2);
					break;
		case 0x01 : sprintf(valuestring, "FW Hang, 0x%02x", pRec->event_data2);
					break;
		case 0x02 : sprintf(valuestring, "FW Progress, %s", getfw02string(pRec->event_data2));
	}

	return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, pStr);
}

// Handling this special OEM sensor by coping what is in byte 4.  I also think that is odd
// considering byte 3 is for sensor reading.  This seems like a misuse of the IPMI spec
int set_sensor_dbus_state_osboot(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
	char valuestring[32];
	char* pStr = valuestring;

	sprintf(valuestring, "%d", pRec->assert_state7_0);

	return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, pStr);
}


//  This table lists only senors we care about telling dbus about.
//  Offset definition cab be found in section 42.2 of the IPMI 2.0 
//  spec.  Add more if/when there are more items of interest.
lookup_t g_ipmidbuslookup[] = {

	{0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
	{0x07, 0x08, set_sensor_dbus_state_simple, "setFault",   "True", "False"},
	{0x0C, 0x06, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
	{0x0C, 0x04, set_sensor_dbus_state_simple, "setFault",   "True", "False"},
	{0x0F, 0x02, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
	{0x0F, 0x01, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
	{0x0F, 0x00, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
	{0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", "False"},
	{0x07, 0x00, set_sensor_dbus_state_simple, "setPresent", "False", "False"}, // OCC Inactive 0
	{0x07, 0x01, set_sensor_dbus_state_simple, "setPresent", "True", "True"},   // OCC Active 1 
	{0xc3, 0x00, set_sensor_dbus_state_osboot, "setValue", "" ,""},

	{0xFF, 0xFF, NULL, "", "", ""}
};



void reportSensorEventAssert(sensorRES_t *pRec, int index) {
	lookup_t *pTable = &g_ipmidbuslookup[index];
	(*pTable->func)(pRec, pTable, pTable->assertion);
}
void reportSensorEventDeassert(sensorRES_t *pRec, int index) {
	lookup_t *pTable = &g_ipmidbuslookup[index];
	(*pTable->func)(pRec, pTable, pTable->deassertion);
}


int findindex(const uint8_t sensor_type, int offset, int *index) {
	
	int i=0, rc=0;
	lookup_t *pTable = g_ipmidbuslookup;

	do {
		if ( ((pTable+i)->sensor_type == sensor_type) && 
			 ((pTable+i)->offset  == offset) ) {
			rc = 1;
			*index = i;
			break;
		}
		i++;
	} while ((pTable+i)->sensor_type  != 0xFF);

	return rc;
}

void debug_print_ok_to_dont_care(uint8_t stype, int offset)
{
	printf("Sensor should not be reported:  Type 0x%02x, Offset 0x%02x\n",
		stype, offset);
}

bool shouldReport(uint8_t sensorType, int offset, int *index) {

	bool rc = false;

	if (findindex(sensorType, offset, index)) { rc = true;	}

	if (rc==false) { debug_print_ok_to_dont_care(sensorType, offset); }

	return rc;
}


int updateSensorRecordFromSSRAESC(const void *record) {

	sensorRES_t *pRec = (sensorRES_t *) record;
	unsigned char stype;
	int index, i=0;
	stype = findSensor(pRec->sensor_number);

	// Scroll through each bit position .  Determine 
	// if any bit is either asserted or Deasserted.
	for(i=0;i<8;i++) {
		if ((ISBITSET(pRec->assert_state7_0,i))  &&
			(shouldReport(stype, i, &index)))
		{
			reportSensorEventAssert(pRec, index);
		}
		if ((ISBITSET(pRec->assert_state14_8,i+8))  &&
			(shouldReport(stype, i+8, &index)))
		{
			reportSensorEventAssert(pRec, index);
		}
		if ((ISBITSET(pRec->deassert_state7_0,i))  &&
			(shouldReport(stype, i, &index)))
		{
			reportSensorEventDeassert(pRec, index);
		}
		if ((ISBITSET(pRec->deassert_state14_8,i+8))  &&
			(shouldReport(stype, i+8, &index)))
		{
			reportSensorEventDeassert(pRec, index);
		}
	}

	return 0;
}
