#!/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_items.py [system name]"
	exit(1)
System = __import__(sys.argv[1])
import Openbmc


INTF_NAME = 'org.openbmc.InventoryItem'
DBUS_NAME = 'org.openbmc.managers.Inventory'

FRUS = System.FRU_INSTANCES
FRU_PATH = System.FRU_PATH

class Inventory(dbus.service.Object):
	def __init__(self,bus,name):
		dbus.service.Object.__init__(self,bus,name)
		self.objects = [ ]

	def addItem(self,item):
		self.objects.append(item)

	@dbus.service.method("org.openbmc.managers.Inventory",
		in_signature='', out_signature='a{sa{sv}}')
	def getItems(self):
		tmp_obj = {}
		for item in self.objects:
			tmp_obj[str(item.item['name'])]=item.getItemDict()
		return tmp_obj
			


class InventoryItem(dbus.service.Object):
	def __init__(self,bus,name):
		dbus.service.Object.__init__(self,bus,name)
		## store all properties in a dict so can easily
		## send on dbus
		self.item = {
			'name' : name,
			'is_fru' : False,
			'fru_type' : 0,
			'state'  : 0,
			'data' : { 'manufacturer' : "" }
		}
		self.cache = True

	def getItemDict(self):
		return self.item

	@dbus.service.method('org.openbmc.InventoryItem',
		in_signature='a{sv}', out_signature='')
	def update(self,data):
		## translate dbus data into basic data types
		for k in data.keys():
			d = Openbmc.DbusProperty(k,data[k])
			self.item['data'][str(k)] = d.getBaseValue()
		self.saveToCache()

	@dbus.service.method("org.openbmc.SensorValue",
		in_signature='y', out_signature='')
	def setValue(self,data):
		self.item['state'] = data
		print "Update Fru State: "+str(self.item['state'])

	def setField(self,field,value):
		self.item['data'][field] = value

	def isCached(self):
		return self.cache

	def getCacheFilename(self):
		global FRU_PATH
		name = self.item['name'].replace('/','.')
		filename = FRU_PATH+name[1:]+".fru"
		return filename
	
	def saveToCache(self):
		if (self.isCached() == False):
			return
		print "Caching: "+self.item['name']
		try: 
			output = open(self.getCacheFilename(), 'wb')
			## just pickle dict not whole object
			cPickle.dump(self.item['data'],output)
		except Exception as e:
			print "ERROR: "+str(e)
		finally:
			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
			try:	
				p = open(filename, 'rb')
				data2 = cPickle.load(p)
				for k in data2.keys():
					self.item['data'][k] = data2[k]
			except Exception as e:
				print "ERROR: " +str(e)
			finally:
				p.close()


if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    bus = dbus.SessionBus()
    name = dbus.service.BusName(DBUS_NAME,bus)
    mainloop = gobject.MainLoop()
    obj_parent = Inventory(bus, '/org/openbmc/managers/Inventory')

    for f in FRUS.keys():
	obj_path=f.replace("<inventory_root>",System.INVENTORY_ROOT)
    	obj = InventoryItem(bus,obj_path)
	obj.setField('is_fru',FRUS[f]['is_fru'])
	obj.setField('fru_type',FRUS[f]['fru_type'])
	obj.loadFromCache();
	obj_parent.addItem(obj)
	
    print "Running Inventory Manager"
    mainloop.run()

