#!/usr/bin/python

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


def fix_byte(it,key,parent):   
    if (isinstance(it,dbus.Array)):
        for i in range(0,len(it)): 
            fix_byte(it[i],i,it)
    elif (isinstance(it, dict)):   
        for key in it.keys():      
            fix_byte(it[key],key,it)
    elif (isinstance(it,dbus.Byte)):   
        if (key != None):              
                parent[key] = int(it)  
    else:                              
        pass                           
                     

def printDict(name,data):
    	if (isinstance(data, dict)):   
		print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
		print name
		for p in sorted(data.keys()):
			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/control/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',
	},
	'state' : { 
		'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.Sensors',
		'object_name' : '/org/openbmc/sensors/host/BootProgress',
		'interface_name' : 'org.openbmc.SensorValue'
	},
	'biosupdate' : {
		'bus_name' : 'org.openbmc.control.Flash',
		'object_name' : '/org/openbmc/control/flash/bios',
		'interface_name' : 'org.openbmc.Flash',
		'method' : 'updateViaTftp',
	},
	'biosflash' : {
		'bus_name' : 'org.openbmc.control.Flash',
		'object_name' : '/org/openbmc/control/flash/bios',
		'interface_name' : 'org.openbmc.Flash',
	},
	'bmcupdate' : {
		'bus_name' : 'org.openbmc.control.Flash',
		'object_name' : '/org/openbmc/control/flash/bmc',
		'interface_name' : 'org.openbmc.Flash',
		'method' : 'updateViaTftp',
	},
	'bmcflash' : {
		'bus_name' : 'org.openbmc.control.Flash',
		'object_name' : '/org/openbmc/control/flash/bmc',
		'interface_name' : 'org.openbmc.Flash',
	},
	'getinventory' : {
		'bus_name' : 'org.openbmc.Inventory',
		'object_name' : '/org/openbmc/inventory',
		'interface_name' : 'org.openbmc.Object.Enumerate',
		'method' : 'enumerate'
	},
	'getsensors' : {
		'bus_name' : 'org.openbmc.Sensors',
		'object_name' : '/org/openbmc/sensors',
		'interface_name' : 'org.openbmc.Object.Enumerate',
		'method' : 'enumerate'
	},
	'host' : {
		'bus_name' : 'org.openbmc.control.Host',
		'object_name' : '/org/openbmc/control/host0',
		'interface_name' : 'org.openbmc.control.Host',
	},
	'setdebugmode' : {
		'bus_name' : 'org.openbmc.control.Host',
		'object_name' : '/org/openbmc/control/host0',
		'interface_name' : 'org.openbmc.control.Host',
		'property' : 'debug_mode'
	},
}

bus = dbus.SystemBus()


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

		print "\t"+name+m
	exit(0)

method_name = ""
property_name = ""

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

if (objinfo.has_key('method')):
	method_name = objinfo['method']
elif (objinfo.has_key('property')):
	property_name = objinfo['property']
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,introspect=False)

if (method_name != ""):
	methd = obj.get_dbus_method(method_name,intf_name)
	try:
		data = methd(*sys.argv)
		fix_byte(data,None,None)	
		pydata = json.loads(json.dumps(data))
		printDict("",pydata)
	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"
elif (property_name != ""):
	intf = dbus.Interface(obj,"org.freedesktop.DBus.Properties")
	property_value = eval(sys.argv.pop(0))
	intf.Set(intf_name,property_name,property_value)
else:
	intf = dbus.Interface(obj,"org.freedesktop.DBus.Properties")
	props = intf.GetAll(intf_name)	
	for p in props:
		print p+" = "+str(props[p])
	
		

