#!/usr/bin/python

import sys
import dbus
import argparse

from dbus.mainloop.glib import DBusGMainLoop
import gobject
import os
import signal
import time
from subprocess import Popen

import obmc_system_config
import obmc.system

descriptors = {
    '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',
        'monitor': 'obmc-chassis-poweron@0.target',
    },
    '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',
        'monitor': 'obmc-chassis-hard-poweroff@0.target',
    },
    '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',
        'monitor': 'obmc-host-start@0.target',
    },
    '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',
        'monitor': 'obmc-host-stop@0.target',
    },
    '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',
    },
    'state' : ['bmcstate', 'chassisstate', 'hoststate']
}

def run_set_property(dbus_bus, dbus_iface, descriptor, args):
    mainloop = gobject.MainLoop()

    iface = descriptor['interface_name']
    prop = descriptor['property']

    if 'monitor' not in descriptor:
        dbus_iface.Set(iface, prop, descriptor['value'])
        return True

    def property_listener(job, path, unit, state):
        if descriptor['monitor'] != unit:
            return

        property_listener.success = (state == 'done')
        mainloop.quit()

    property_listener.success = True

    if args.wait and args.verbose:
        pid = Popen(["/bin/journalctl", "-f", "--no-pager"]).pid

    if args.wait:
        sig_match = dbus_bus.add_signal_receiver(property_listener, "JobRemoved")

    dbus_iface.Set(iface, prop, descriptor['value'])

    if args.wait:
        mainloop.run()
        sig_match.remove()

    if args.wait and args.verbose:
        # wait some time for the journal output
        time.sleep(args.wait_tune)
        os.kill(pid, signal.SIGTERM)

    return property_listener.success

def get_dbus_obj(dbus_bus, bus, obj, args):
    if not args.wait:
        return dbus_bus.get_object(bus, obj)

    mainloop = gobject.MainLoop()

    def property_listener(job, path, unit, state):
        if 'obmc-standby.target' == unit:
            mainloop.quit()

    sig_match = dbus_bus.add_signal_receiver(property_listener, "JobRemoved")
    try:
        return dbus_bus.get_object(bus, obj)
    except dbus.exceptions.DBusException as e:
        if args.verbose:
            pid = Popen(["/bin/journalctl", "-f", "--no-pager"]).pid

        mainloop.run()

        if args.verbose:
            os.kill(pid, signal.SIGTERM)
    finally:
        sig_match.remove()

    return dbus_bus.get_object(bus, obj)

def run_one_command(dbus_bus, descriptor, args):
    bus = descriptor['bus_name']
    obj = descriptor['object_name']
    iface = descriptor['interface_name']
    dbus_obj = get_dbus_obj(dbus_bus, bus, obj, args)
    result = None

    if 'property' in descriptor:
        dbus_iface = dbus.Interface(dbus_obj, "org.freedesktop.DBus.Properties")
        if 'value' in descriptor:
            result = run_set_property(dbus_bus, dbus_iface, descriptor, args)
        else:
            prop = descriptor['property']
            dbus_prop = dbus_iface.Get(iface, prop)
            print '{:<20}: {}'.format(prop, str(dbus_prop))
            result = True
    else:
        dbus_iface = dbus.Interface(dbus_obj, "org.freedesktop.DBus.Properties")
        props = dbus_iface.GetAll(iface)
        for p in props:
            print "{} = {}".format(p, str(props[p]))
        result = True

    return result

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

    assert isinstance(recipe, list)
    for command in recipe:
        descriptor = descriptors[command]
        if not run_one_command(dbus_bus, descriptor, args):
            print "Failed to execute command: {}".format(descriptor)
            return False

    return True

def gpio_set_value(gpio_name, active_low, asserted):
    gpio_id = obmc.system.convertGpio(gpio_name)
    gpio_value_path = "/sys/class/gpio/gpio{}/value".format(gpio_id)

    with open(gpio_value_path, 'w') as gpio:
        # Inversion behaviour needs to change with the resolution of
        # https://github.com/openbmc/openbmc/issues/2489, where properly
        # configuring the kernel will allow it to handle the inversion for us.
        gpio.write(str(int(asserted ^ active_low)))

    return True

def gpio_deassert(gpio_name, active_low, args):
    # Deal with silly python2 exception handling as outlined in main
    if args.verbose:
        return gpio_set_value(gpio_name, active_low, False)

    try:
        return gpio_set_value(gpio_name, active_low, False)
    except IOError as e:
        print >> sys.stderr, "Failed to access GPIO {}: {}".format(gpio_name, e.message)
        return False

def run_chassiskill(args):
    # We shouldn't be able to invoke run_chassiskill() unless it's been
    # explicitly added as a valid command to argparse in main()
    assert can_chassiskill()

    # Multi-dimensional fetch is now exception-safe
    gpios = obmc_system_config.GPIO_CONFIGS['power_config']['power_up_outs']

    gc = obmc_system_config.GPIO_CONFIG

    for gpio in gpios:
        function = gpio[0]

        if function not in gc or 'gpio_pin' not in gc[function]:
            print >> sys.stderr, "Missing or invalid definition for '{}' in system GPIO_CONFIG".format(function)
            continue

        name = gc[function]['gpio_pin']

        # The second element of the tuples stashed in 'power_up_outs'
        # represents the boolean condition of the statement 'active high'. To
        # mirror the code at [1] we instead need the condition of the statement
        # 'active low', thus we negate gpio[1].
        #
        # [1] https://github.com/openbmc/skeleton/blob/93b84e42834893313616f96c70743369f26a7190/op-pwrctl/power_control_obj.c#L283
        active_low = not gpio[1]

        if not gpio_deassert(name, active_low, args):
            return False

    return True

def can_chassiskill():
    gcs = obmc_system_config.GPIO_CONFIGS

    if 'power_config' in gcs:
        if 'power_up_outs' in gcs['power_config']:
            # Just to be sure
            return len(gcs['power_config']) > 0

    return False

def main():
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    # Conditionally add the `chassiskill` command based on whether the
    # required GPIO configuration is present in the system description.
    if can_chassiskill():
        descriptors['chassiskill'] = None

    parser = argparse.ArgumentParser()
    parser.add_argument('--verbose', '-v', action='store_true',
            help="Verbose output")
    parser.add_argument('--wait', '-w', action='store_true',
            help='Block until the state transition succeeds or fails')
    parser.add_argument('--wait-tune', '-t', nargs='?', default=8, type=float,
            # help='Seconds to wait for journal output to complete after receiving DBus signal',
            help=argparse.SUPPRESS)
    parser.add_argument('recipe', choices=sorted(descriptors.keys()))
    args = parser.parse_args()

    # This is a special case: directly pull the power, don't do any D-Bus
    # related stuff
    if args.recipe == "chassiskill":
        return run_chassiskill(args)

    dbus_bus = dbus.SystemBus()

    # The only way to get a sensible backtrace with python 2 without stupid
    # hoops is to let the uncaught exception handler do the work for you.
    # Catching and binding an exception appears to overwrite the stack trace at
    # the point of bind.
    #
    # So, if we're in verbose mode, don't try to catch the DBus exception. That
    # way we can understand where it originated.
    if args.verbose:
        return run_all_commands(dbus_bus, descriptors[args.recipe], args)

    # Otherwise, we don't care about the traceback. Just catch it and print the
    # error message.
    try:
        return run_all_commands(dbus_bus, descriptors[args.recipe], args)
    except dbus.exceptions.DBusException as e:
        print >> sys.stderr, "DBus error occurred: {}".format(e.get_dbus_message())
    finally:
        dbus_bus.close()

if __name__ == "__main__":
    sys.exit(0 if main() else 1)
