#!/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 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'
    },
    'chassison': {
        'bus_name': 'xyz.openbmc_project.State.Chassis',
        'object_name': '/xyz/openbmc_project/state/chassis0',
        'interface_name': 'xyz.openbmc_project.State.Chassis',
        'property': 'RequestedPowerTransition',
        'value': 'xyz.openbmc_project.State.Chassis.Transition.On'
    },
    'chassisoff': {
        'bus_name': 'xyz.openbmc_project.State.Chassis',
        'object_name': '/xyz/openbmc_project/state/chassis0',
        'interface_name': 'xyz.openbmc_project.State.Chassis',
        'property': 'RequestedPowerTransition',
        'value': 'xyz.openbmc_project.State.Chassis.Transition.Off'
    },
    'poweron': {
        'bus_name': 'xyz.openbmc_project.State.Host',
        'object_name': '/xyz/openbmc_project/state/host0',
        'interface_name': 'xyz.openbmc_project.State.Host',
        'property': 'RequestedHostTransition',
        'value': 'xyz.openbmc_project.State.Host.Transition.On'
    },
    'poweroff': {
        'bus_name': 'xyz.openbmc_project.State.Host',
        'object_name': '/xyz/openbmc_project/state/host0',
        'interface_name': 'xyz.openbmc_project.State.Host',
        'property': 'RequestedHostTransition',
        'value': 'xyz.openbmc_project.State.Host.Transition.Off'
    },
    'bmcstate': {
        'bus_name': 'xyz.openbmc_project.State.BMC',
        'object_name': '/xyz/openbmc_project/state/bmc0',
        'interface_name': 'xyz.openbmc_project.State.BMC',
        'property': 'CurrentBMCState',
    },
    'chassisstate': {
        'bus_name': 'xyz.openbmc_project.State.Chassis',
        'object_name': '/xyz/openbmc_project/state/chassis0',
        'interface_name': 'xyz.openbmc_project.State.Chassis',
        'property': 'CurrentPowerState',
    },
    'hoststate': {
        'bus_name': 'xyz.openbmc_project.State.Host',
        'object_name': '/xyz/openbmc_project/state/host0',
        'interface_name': 'xyz.openbmc_project.State.Host',
        'property': 'CurrentHostState',
    },
    'bootprogress': {
        'bus_name': 'org.openbmc.Sensors',
        'object_name': '/org/openbmc/sensors/host/BootProgress',
        'interface_name': 'org.openbmc.SensorValue'
    },
}

# Commands that need to run multiple objects above
multicmd_objects = { 'state' : ['bmcstate', 'chassisstate', 'hoststate'] }

bus = dbus.SystemBus()

if (len(sys.argv) == 1 or sys.argv[1] == "-h" or
        (not(dbus_objects.has_key(sys.argv[1])) and
        (not(multicmd_objects.has_key(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 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
    print "Multi-Commands:"
    for name in sorted(multicmd_objects.keys()):
        print "\t" + name + " -> " + ",".join(multicmd_objects[name])
    exit(0)

method_name = ""
property_name = ""

sys.argv.pop(0)
cmd = [sys.argv.pop(0)]

# Check if this is a multicmd command and update if it is
if(multicmd_objects.has_key(cmd[0])):
    cmd = multicmd_objects[cmd[0]]

for c in cmd:
    objinfo = dbus_objects[c]
    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")
        if (objinfo.has_key('value')):
            property_value = objinfo['value']
        else:
            if(len(sys.argv) > 0):
                property_value = eval(sys.argv.pop(0))
            else:
                property_value = None
        if(property_value is not None):
            intf.Set(intf_name, property_name, property_value)
        else:
            prop = intf.Get(intf_name,property_name)
            print '{:<20}'.format(property_name+": ") + str(prop)
    else:
        intf = dbus.Interface(obj, "org.freedesktop.DBus.Properties")
        props = intf.GetAll(intf_name)
        for p in props:
            print p + " = " + str(props[p])
