#!/usr/bin/python

import sys
import dbus
import argparse

from dbus.mainloop.glib import DBusGMainLoop
import gobject
import json
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'],
    'status' : ['bmcstate', 'chassisstate', 'hoststate'],
}

GPIO_DEFS_FILE = '/etc/default/obmc/gpio/gpio_defs.json'

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()

    data = {}
    with open(GPIO_DEFS_FILE, 'r') as json_input:
        data = json.load(json_input)

    gpios = data['gpio_configs']['power_config']['power_up_outs']
    defs = data['gpio_definitions']

    for gpio in gpios:

        definition = filter(lambda g: g['name'] == gpio['name'], defs)
        if len(definition) == 0:
            print >> sys.stderr, "Missing definition for GPIO {}".format(gpio['name'])
            continue

        pin = str(definition[0]['pin'])
        active_low = not gpio['polarity']

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

    return True

def can_chassiskill():

    try:
        with open(GPIO_DEFS_FILE, 'r') as json_input:
            data = json.load(json_input)
            gpios = data['gpio_configs']['power_config']['power_up_outs']
            return len(gpios) > 0
    except:
        pass

    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)
