#!/usr/bin/python

import sys
import dbus
import json
import xml.etree.ElementTree as ET


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)
    elif (isinstance(it, dbus.Double)):
        if (key != None):
            parent[key] = float(it)
    else:
        pass


def merge_interfaces(objs):
    for op in objs:
        merged = {}
        for interface, properties in objs[op].items():
            merged.update(properties)

        del objs[op]
        objs[op] = merged


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.BmcFlash',
        'object_name': '/org/openbmc/control/flash/bmc',
        'interface_name': 'org.openbmc.control.BmcFlash',
        'method': 'updateViaTftp',
    },
    'bmcflash': {
        'bus_name': 'org.openbmc.control.BmcFlash',
        'object_name': '/org/openbmc/control/flash/bmc',
        'interface_name': 'org.openbmc.control.BmcFlash',
    },
    'getinventory': {
        'bus_name': 'org.openbmc.Inventory',
        'object_name': '/org/openbmc/inventory',
        'interface_name': 'org.freedesktop.DBus.ObjectManager',
        'method': 'GetManagedObjects',
        'transform': merge_interfaces
    },
    'getsensors': {
        'bus_name': 'org.openbmc.Sensors',
        'object_name': '/org/openbmc/sensors',
        'interface_name': 'org.freedesktop.DBus.ObjectManager',
        'method': 'GetManagedObjects',
        'transform': merge_interfaces
    },
    '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)

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))
        if 'transform' in objinfo:
            objinfo['transform'](pydata)
        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])