#!/usr/bin/python

import sys
import dbus

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': 'xyz.openbmc_project.State.Host',
        'object_name': '/xyz/openbmc_project/state/host0',
        'interface_name': 'xyz.openbmc_project.State.Boot.Progress',
        'property': 'BootProgress',
    },
}

def run_one_command(dbus_bus, objinfo):
    bus = objinfo['bus_name']
    obj = objinfo['object_name']
    iface = objinfo['interface_name']
    dbus_obj = dbus_bus.get_object(bus, obj)

    if (objinfo.has_key('property')):
        prop = objinfo['property']
        dbus_iface = dbus.Interface(dbus_obj, "org.freedesktop.DBus.Properties")
        if objinfo.has_key('value'):
            dbus_iface.Set(iface, prop, objinfo['value'])
        else:
            dbus_prop = dbus_iface.Get(iface, prop)
            print '{:<20}: {}'.format(prop, str(dbus_prop))
    else:
        dbus_iface = dbus.Interface(dbus_obj, "org.freedesktop.DBus.Properties")
        props = dbus_iface.GetAll(iface)
        for p in props:
            print p + " = " + str(props[p])

def run_all_commands(dbus_bus, commands):
    if isinstance(commands, dict):
        run_one_command(dbus_bus, commands)
        return

    assert isinstance(commands, list)
    for command in commands:
        run_one_command(dbus_bus, dbus_objects[command])

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

    dbus_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]"
        print "Available commands:"
        for name in sorted(dbus_objects.keys()):
            m = ""
            if (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)

    sys.argv.pop(0)
    recipe = sys.argv.pop(0)

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

    run_all_commands(dbus_bus, recipe)

if __name__ == "__main__":
    main()
