#!/usr/bin/env python

import os
import sys
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
import cPickle
import json

if (len(sys.argv) < 2):
	print "Usage:  inventory_manager.py [system name]"
	exit(1)
System = __import__(sys.argv[1])
import Openbmc

DBUS_NAME = 'org.openbmc.managers.Inventory'
OBJ_NAME = '/org/openbmc/managers/Inventory'
FRUS = System.FRU_INSTANCES
FRU_PATH = System.FRU_PATH

## accessor class to FRU data structure
class Fru:
	def __init__(self,fru):
		## validation
		if (FRUS.has_key(fru) == False):
			# TODO: event log
			raise Exception("Invalid FRU path: "+fru)
		
		self.fru = fru
	
	def getField(self,field):
		if (FRUS[self.fru].has_key(field) == False):
			# TODO: event log
			raise Exception("Invalid field: "+field)
			
		return FRUS[self.fru][field]

	def isFru(self):
		return FRUS[self.fru]['fru']

	def update(self,data):
		for k in data.keys():
			FRUS[self.fru][k] = data[k]

	def isCached(self):
		return True

	def getCacheFilename(self):
		global FRU_PATH
		name = self.fru.replace('/','.')
		filename = FRU_PATH+name[1:]+".fru"
		return filename
	
	def saveToCache(self):
		if (self.isCached() == False):
			return
		print "Caching: "+self.fru
		# TODO: error handling
		output = open(self.getCacheFilename(), 'wb')
		## just pickle dict not whole object
		cPickle.dump(FRUS[self.fru],output)
		output.close()

	def loadFromCache(self):
		if (self.isCached() == False):
			return;
		## overlay with pickled data
		filename=self.getCacheFilename()
		if (os.path.isfile(filename)):
			print "Loading from cache: "+filename
			# TODO: error handling
			p = open(filename, 'rb')
			data2 = cPickle.load(p)
			for k in data2.keys():
				FRUS[self.fru][k] = data2[k]

	def __str__(self):	
		r = "Fru: "+str(self.fru_id)+"\n"
		for f in self.data.keys():
			r = r+f+" = "+str(self.data[f])+"\n"
		return r

		

class InventoryManager(dbus.service.Object):
	def __init__(self,bus,name):
		dbus.service.Object.__init__(self,bus,name)
		
		bus.add_signal_receiver(self.UpdateFruHandler,
					dbus_interface = "org.openbmc.sensors.IpmiBt", 
					signal_name = 'UpdateFru')

		bus.add_signal_receiver(self.SetSensorHandler, 
					dbus_interface = "org.openbmc.sensors.IpmiBt", 
					signal_name = "SetSensor")

		self.fru_db = {}
		self.fru_id_lookup = {}
		self.sensor_id_lookup = {}

		for fru_path in FRUS.keys():
			self.addFru(fru_path)
			f = FRUS[fru_path]
			if (f.has_key('fru_id')):
				self.fru_id_lookup[f['fru_id']] = fru_path
			if (f.has_key('sensor_id')):
				self.sensor_id_lookup[f['sensor_id']] = fru_path

	@dbus.service.signal('org.openbmc.EventLog')
	def EventLog(self, priority, message, rc):
        	pass
		
	def UpdateFruHandler(self,fru_id,data):
		self.updateFruFromId(fru_id,data)		

	def SetSensorHandler(self,sensor_id,data):
		fru_path = self.getFruSensor(sensor_id)
		if (fru_path != ""):
			state = { 'state' : data }
			self.updateFru(fru_path,state)
			
	@dbus.service.method(DBUS_NAME,
		in_signature='y', out_signature='s')	
	def getFruSensor(self,sensor_id):
		if (self.sensor_id_lookup.has_key(sensor_id) == False):
			return ""
		return self.sensor_id_lookup[sensor_id]
		
	def addFru(self,fru_path):
		new_fru = Fru(fru_path)
		new_fru.loadFromCache()
		self.fru_db[fru_path] = new_fru
				
	@dbus.service.method(DBUS_NAME,
		in_signature='ia{sv}', out_signature='')
	def updateFruFromId(self,fru_id,data):
		iid = int(fru_id)
		if (self.fru_id_lookup.has_key(iid) == False):
			self.EventLog(1,"FRU ID not found: "+str(iid),1)
		else:
			self.updateFru(self.fru_id_lookup[iid],data)
		

	@dbus.service.method(DBUS_NAME,
		in_signature='sa{sv}', out_signature='')
	def updateFru(self,fru_path,data):
		## translate dbus data into basic data types
		clean_data = {}
		for k in data.keys():
			d = Openbmc.DbusProperty(k,data[k])
			clean_data[str(k)] = d.getBaseValue()

		if (self.fru_db.has_key(fru_path)):
			## update properties then save to cache
			print "Updating FRU: "+fru_path
			self.fru_db[fru_path].update(clean_data)
			self.fru_db[fru_path].saveToCache()


	@dbus.service.method(DBUS_NAME,
		in_signature='', out_signature='a{sa{sv}}')
	def getFrus(self):
		return FRUS


if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    bus = dbus.SessionBus()
    name = dbus.service.BusName(DBUS_NAME,bus)
    obj = InventoryManager(bus,OBJ_NAME)
    mainloop = gobject.MainLoop()

    print "Running Inventory Manager"
    mainloop.run()

