import dbus
import xml.etree.ElementTree as ET

BUS_PREFIX = 'org.openbmc'
OBJ_PREFIX = "/org/openbmc"
GPIO_DEV = '/sys/class/gpio'
BUS = "system"

FRU_TYPES = {
	'SYSTEM' : 0,
	'CPU' : 1,
	'DIMM' : 2,
	'MAIN_PLANAR' : 3,
	'RISER_CARD' : 4,
	'FAN' : 5,
	'BMC' : 6,
	'CORE' : 7,
	'PCIE_CARD' : 8,
}
FRU_STATES = {
	'NORMAL'            : 0,
	'RECOVERABLE_ERROR' : 1,
	'FATAL_ERROR'       : 2,
	'NOT_PRESENT'       : 3,
}


ENUMS = {
	'org.openbmc.SensorIntegerThreshold.state' : 
		['NOT_SET','NORMAL','LOWER_CRITICAL','LOWER_WARNING','UPPER_WARNING','UPPER_CRITICAL'],
}

DBUS_TO_BASE_TYPES = {
	'dbus.Byte' : 'int',
	'dbus.Double' : 'float',
	'dbus.Int32' : 'int',
	'dbus.UInt32' : 'long',
	'dbus.String' : 'str',
	'dbus.UInt64' : 'long',
	'dbus.Boolean' : 'bool',
}

BASE_TO_DBUS_TYPES = {
	'int'   : 'dbus.Int32',
	'float' : 'dbus.Double',
	'str'   : 'dbus.String',
	'long'  : 'dbus.Int64',
	'bool'  : 'dbus.Boolean'
}

def getDBus():
	bus = None
	if (BUS == "session"):
		bus = dbus.SessionBus()
	else:
		bus = dbus.SystemBus()
	return bus


def getManagerInterface(bus,manager):
	bus_name = "org.openbmc.managers."+manager
	obj_name = "/org/openbmc/managers/"+manager
	obj = bus.get_object(bus_name,obj_name)
	return dbus.Interface(obj,bus_name)


def get_objs(bus,bus_name,path,objects):
	tmp_path = path
	if (path == ""):
		tmp_path="/"
	obj = bus.get_object(bus_name,tmp_path)
	introspect_iface = dbus.Interface(obj,"org.freedesktop.DBus.Introspectable")
 	tree = ET.ElementTree(ET.fromstring(introspect_iface.Introspect()))
 	root = tree.getroot()
	parent = True
	for node in root.iter('node'):
		for intf in node.iter('interface'):
			intf_name = intf.attrib['name']
			parts=path.split('/')
			instance = parts[len(parts)-1]
			if (objects.has_key(instance) == False):
				objects[instance] = {}
				objects[instance]['PATH'] = path
				objects[instance]['INIT'] = []
			for method in intf.iter('method'):
				if (method.attrib['name'] == "init"):
					objects[instance]['INIT'].append(intf_name)

		if (node.attrib.has_key('name') == True):
			node_name = node.attrib['name']
			if (parent == False):
				get_objs(bus,bus_name,path+"/"+node_name,objects)
			else:
				if (node_name != "" and node_name != path):
					get_objs(bus,bus_name,node_name,objects)
			
		parent = False


class DbusProperty:
	def __init__(self,name,value):
		self.name = str(name)	
		self.dbusType = str(type(value)).split("'")[1]
		self.variant_level = 2
		self.value = None
		if (BASE_TO_DBUS_TYPES.has_key(self.dbusType) == False):
			self.variant_level = value.variant_level
			try: 
				self.value = eval(DBUS_TO_BASE_TYPES[self.dbusType]+"(value)")
			except:
				raise Exception("Unknown dbus type: "+self.dbusType)
		else:
			self.dbusType = BASE_TO_DBUS_TYPES[self.dbusType]
			self.value = value

	def setValue(self,value):
		try: 
			self.value = eval(DBUS_TO_BASE_TYPES[self.dbusType]+"(value)")
		except:
			raise Exception("Unknown dbus type: "+self.dbusType)

	def setVariant(self,variant_level):
		self.variant_level = variant_level

	def getName(self):
		return self.name

	def getValue(self):
		e = self.dbusType+"(self.value, variant_level="+str(self.variant_level)+")"
		return eval(e)

	def getBaseValue(self):
		return self.value

	def __str__(self):
		return self.dbusType+":"+str(self.value)
