#!/usr/bin/python -u

import sys
import uuid
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
from obmc.dbuslib.bindings import get_dbus, DbusProperties, DbusObjectManager

DBUS_NAME = 'org.openbmc.control.Chassis'
OBJ_NAME = '/org/openbmc/control/chassis0'
CONTROL_INTF = 'org.openbmc.Control'

MACHINE_ID = '/etc/machine-id'

POWER_OFF = 0
POWER_ON = 1

BOOTED = 100


class ChassisControlObject(DbusProperties, DbusObjectManager):
    def getUuid(self):
        uuid = "";
        try:
            with open(MACHINE_ID) as f:
                data = f.readline().rstrip('\n')
                if (len(data) == 32):
                    uuid = data
                else:
                    print "ERROR:  UUID is not formatted correctly: " + data
        except:
            print "ERROR: Unable to open uuid file: " + MACHINE_ID

        return uuid

    def __init__(self, bus, name):
        self.dbus_objects = {}
        DbusProperties.__init__(self)
        DbusObjectManager.__init__(self)
        dbus.service.Object.__init__(self, bus, name)
        ## load utilized objects
        self.dbus_objects = {
            'power_control': {
                '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'
            },
            'watchdog': {
                'bus_name': 'org.openbmc.watchdog.Host',
                'object_name': '/org/openbmc/watchdog/host0',
                'interface_name': 'org.openbmc.Watchdog'
            },
            'host_services': {
                'bus_name': 'org.openbmc.HostServices',
                'object_name': '/org/openbmc/HostServices',
                'interface_name': 'org.openbmc.HostServices'
            },
            'settings': {
                'bus_name': 'org.openbmc.settings.Host',
                'object_name': '/org/openbmc/settings/host0',
                'interface_name': 'org.freedesktop.DBus.Properties'
            },
            'host_control': {
                'bus_name': 'org.openbmc.control.Host',
                'object_name': '/org/openbmc/control/host0',
                'interface_name': 'org.openbmc.control.Host'
            },
        }

        # uuid
        self.Set(DBUS_NAME, "uuid", self.getUuid())
        self.Set(DBUS_NAME, "reboot", 0)

        bus.add_signal_receiver(self.power_button_signal_handler,
                                dbus_interface="org.openbmc.Button",
                                signal_name="Released",
                                path="/org/openbmc/buttons/power0")
        bus.add_signal_receiver(self.long_power_button_signal_handler,
                                dbus_interface="org.openbmc.Button",
                                signal_name="PressedLong",
                                path="/org/openbmc/buttons/power0")
        bus.add_signal_receiver(self.softreset_button_signal_handler,
                                dbus_interface="org.openbmc.Button",
                                signal_name="Released",
                                path="/org/openbmc/buttons/reset0")

        bus.add_signal_receiver(self.host_watchdog_signal_handler,
                                dbus_interface="org.openbmc.Watchdog",
                                signal_name="WatchdogError")

        bus.add_signal_receiver(self.emergency_shutdown_signal_handler,
                                dbus_interface="org.openbmc.SensorThresholds",
                                signal_name="Emergency")

        bus.add_signal_receiver(self.SystemStateHandler,
                                signal_name="GotoSystemState")
        self.InterfacesAdded(name, self.properties)


    def getInterface(self, name):
        o = self.dbus_objects[name]
        obj = bus.get_object(o['bus_name'], o['object_name'], introspect=False)
        return dbus.Interface(obj, o['interface_name'])


    @dbus.service.method(DBUS_NAME,
                         in_signature='', out_signature='')
    def setIdentify(self):
        print "Turn on identify"
        intf = self.getInterface('identify_led')
        intf.setOn()
        return None

    @dbus.service.method(DBUS_NAME,
                         in_signature='', out_signature='')
    def clearIdentify(self):
        print "Turn on identify"
        intf = self.getInterface('identify_led')
        intf.setOff()
        return None

    @dbus.service.method(DBUS_NAME,
                         in_signature='', out_signature='')
    def powerOn(self):
        print "Turn on power and boot"
        self.Set(DBUS_NAME, "reboot", 0)
        if (self.getPowerState() == 0):
            intf = self.getInterface('power_control')
            intf.setPowerState(POWER_ON)
        return None

    @dbus.service.method(DBUS_NAME,
                         in_signature='', out_signature='')
    def powerOff(self):
        print "Turn off power"
        intfwatchdog = self.getInterface('watchdog')
        intfwatchdog.stop()
        intf = self.getInterface('power_control')
        intf.setPowerState(POWER_OFF)
        return None

    @dbus.service.method(DBUS_NAME,
                         in_signature='', out_signature='')
    def softPowerOff(self):
        print "Soft off power"
        intf = self.getInterface('host_services')
        ## host services will call power off when ready
        intf.SoftPowerOff()
        return None

    @dbus.service.method(DBUS_NAME,
                         in_signature='', out_signature='')
    def reboot(self):
        print "Rebooting"
        if self.getPowerState() == POWER_OFF:
            self.powerOn();
        else:
            self.Set(DBUS_NAME, "reboot", 1)
            self.powerOff()
        return None

    @dbus.service.method(DBUS_NAME,
                         in_signature='', out_signature='')
    def softReboot(self):
        print "Soft Rebooting"
        if self.getPowerState() == POWER_OFF:
            self.powerOn();
        else:
            self.Set(DBUS_NAME, "reboot", 1)
            self.softPowerOff()
        return None

    @dbus.service.method(DBUS_NAME,
                         in_signature='', out_signature='i')
    def getPowerState(self):
        intf = self.getInterface('power_control')
        return intf.getPowerState()

    ## Signal handler

    def SystemStateHandler(self, state_name):
        if (
                state_name == "HOST_POWERED_OFF" or state_name == "HOST_POWERED_ON"):
            intf = self.getInterface('settings')
            intf.Set("org.openbmc.settings.Host", "system_state", state_name)

        if (state_name == "HOST_POWERED_OFF" and self.Get(DBUS_NAME,
                                                          "reboot") == 1):
            self.powerOn()

    def power_button_signal_handler(self):
        # power on
        state = self.getPowerState()
        if state == POWER_OFF:
            self.powerOn()

    def long_power_button_signal_handler(self):
        print "Long-press button, hard power off"
        self.powerOff();

    def softreset_button_signal_handler(self):
        self.softReboot();

    def host_watchdog_signal_handler(self):
        print "Watchdog Error, Hard Rebooting"
        self.Set(DBUS_NAME, "reboot", 1)
        self.powerOff()

    def emergency_shutdown_signal_handler(self):
        print "Emergency Shutdown!"
        self.powerOff()


if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    bus = get_dbus()
    name = dbus.service.BusName(DBUS_NAME, bus)
    obj = ChassisControlObject(bus, OBJ_NAME)
    mainloop = gobject.MainLoop()

    print "Running ChassisControlService"
    mainloop.run()

