#!/usr/bin/python

import sys
import subprocess
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
import xml.etree.ElementTree as ET

def isDict(data):
	if (str(type(data)) == "<type \'dbus.Dictionary\'>"):
		return True
	return False
		

def printDict(name,data):
	if (isDict(data)):
		print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
		print name
		for p in data:
			printDict(p,data[p])
	else:
		print name+" = "+str(data)

def introspect(bus_name,obj_path,intf_name,method_name):
	obj = bus.get_object(bus_name,obj_path)
	introspect_iface = dbus.Interface(obj,"org.freedesktop.DBus.Introspectable")
 	tree = ET.ElementTree(ET.fromstring(introspect_iface.Introspect()))
	#print method_name
	#print introspect_iface.Introspect()
 	root = tree.getroot()
	found = False
	for node in root.iter('node'):
		for intf in node.iter('interface'):
			if (intf.attrib['name'] == intf_name):
				for method in intf.iter('method'):
					if (method.attrib['name'] == method_name):
						for ar in method.iter('arg'):
							if (ar.attrib['direction'] == "in"):
								print "\t"+ar.attrib['name']+" ("+ar.attrib['type']+")"
								found = True

	return found


dbus_objects = {
	'power' : { 
		'bus_name' : 'org.openbmc.control.Power',
		'object_name' : '/org/openbmc/control/power0',
		'interface_name' : 'org.openbmc.control.Power'
	},
	'identify_led' : {
		'bus_name' : 'org.openbmc.control.led',
		'object_name' : '/org/openbmc/led/IDENTIFY',
		'interface_name' : 'org.openbmc.Led'
	},	
	'chassis' : { 
		'bus_name' : 'org.openbmc.control.Chassis',
		'object_name' : '/org/openbmc/control/chassis0',
		'interface_name' : 'org.openbmc.control.Chassis'
	},
	'poweron' : { 
		'bus_name' : 'org.openbmc.control.Chassis',
		'object_name' : '/org/openbmc/control/chassis0',
		'interface_name' : 'org.openbmc.control.Chassis',
		'method' : 'powerOn',
	},
	'poweroff' : { 
		'bus_name' : 'org.openbmc.control.Chassis',
		'object_name' : '/org/openbmc/control/chassis0',
		'interface_name' : 'org.openbmc.control.Chassis',
		'method' : 'powerOff',
	},
	'getsystemstate' : { 
		'bus_name' : 'org.openbmc.managers.System',
		'object_name' : '/org/openbmc/managers/System',
		'interface_name' : 'org.openbmc.managers.System',
		'method' : 'getSystemState',
	},
	'bootprogress' : { 
		'bus_name' : 'org.openbmc.sensor.Power8Virtual',
		'object_name' : '/org/openbmc/sensor/virtual/BootProgress',
		'interface_name' : 'org.openbmc.SensorValue'
	},
	'updatebios' : {
		'bus_name' : 'org.openbmc.control.Flash',
		'object_name' : '/org/openbmc/control/flash/bios',
		'interface_name' : 'org.openbmc.Flash',
		'method' : 'updateViaTftp',
	},
	'getinventory' : {
		'bus_name' : 'org.openbmc.managers.Inventory',
		'object_name' : '/org/openbmc/inventory',
		'interface_name' : 'org.openbmc.Object.Enumerate',
		'method' : 'enumerate'
	},
	'getsensors' : {
		'bus_name' : 'org.openbmc.managers.Sensors',
		'object_name' : '/org/openbmc/sensors',
		'interface_name' : 'org.openbmc.Object.Enumerate',
		'method' : 'enumerate'
	},
	'inventorytest' : {
		'bus_name' : 'org.openbmc.managers.Inventory',
		'object_name' : '/org/openbmc/inventory/system/chassis/motherboard/cpu0',
		'interface_name' : 'org.openbmc.InventoryItem',
		'method' : 'update'
	},

}

bus = dbus.SystemBus()


if (len(sys.argv) == 1):
	print "Usage: obmcutil [command] [[method] [*args]]"
	print "\tIf [method] is blank, then all properties are printed\n"
	print "Available commands:"
	for name in dbus_objects:
		m = ""
		if (dbus_objects[name].has_key('method') == True):
			m=" ("+dbus_objects[name]['interface_name']+"->"+dbus_objects[name]['method']+")"
		print "\t"+name+m
	exit(0)

method_name = ""

sys.argv.pop(0)
objinfo = dbus_objects[sys.argv.pop(0)]

if (objinfo.has_key('method')):
	method_name = objinfo['method']
elif (len(sys.argv)>0):
	## if command line args left and method not specified
	## then next arg must be method name
	method_name = sys.argv.pop(0)

bus_name = objinfo['bus_name']
obj_path = objinfo['object_name']
intf_name = objinfo['interface_name']
obj = bus.get_object(bus_name,obj_path)

if (method_name == ""):
	intf = dbus.Interface(obj,"org.freedesktop.DBus.Properties")
	props = intf.GetAll(intf_name)	
	for p in props:
		print p+" = "+str(props[p])
	
else:
	methd = obj.get_dbus_method(method_name,intf_name)
	try:
		## too hard to do dicts from command line
		## hack just to test fru update function
		if (method_name == "update"):
			tmp = { 'manufacturer' : sys.argv[0], 'part_num' : '3Nxxxx' }
			methd(tmp)
		else:
			data = methd(*sys.argv)
			printDict("",data)
	except Exception as e:
		print e
		r = introspect(bus_name,obj_path,intf_name,method_name)
		if (r == False):
			print "ERROR: Invalid method: "+method_name
		else:
			print "ERROR: Incorrect arguments passed to method"
			
		

