#!/usr/bin/env python

# TODO: openbmc/openbmc#2994 remove python 2 support
try:  # python 2
    import gobject
except ImportError:  # python 3
    from gi.repository import GObject as 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 Exception:
            print("ERROR: Unable to open uuid file: " + MACHINE_ID)

        return uuid

    def __init__(self, bus, name):
        super(ChassisControlObject, self).__init__(conn=bus, object_path=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",
            },
            "host_services": {
                "bus_name": "org.openbmc.HostServices",
                "object_name": "/org/openbmc/HostServices",
                "interface_name": "org.openbmc.HostServices",
            },
            "systemd": {
                "bus_name": "org.freedesktop.systemd1",
                "object_name": "/org/freedesktop/systemd1",
                "interface_name": "org.freedesktop.systemd1.Manager",
            },
        }

        # 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",
        )

    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 powerOn(self):
        print("Turn on power and boot")
        self.Set(DBUS_NAME, "reboot", 0)
        intf = self.getInterface("systemd")
        f = getattr(intf, "StartUnit")
        f.call_async("obmc-host-start@0.target", "replace")
        return None

    @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
    def powerOff(self):
        print("Turn off power")
        intf = self.getInterface("systemd")
        f = getattr(intf, "StartUnit")
        f.call_async("obmc-chassis-hard-poweroff@0.target", "replace")
        return None

    @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
    def softPowerOff(self):
        print("Soft off power")
        intf = self.getInterface("systemd")
        f = getattr(intf, "StartUnit")
        f.call_async("obmc-host-shutdown@0.target", "replace")
        return None

    @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
    def reboot(self):
        print("Rebooting")
        if self.getPowerState() != POWER_OFF:
            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.Set(DBUS_NAME, "reboot", 1)
            self.softPowerOff()
        return None

    @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
    def quiesce(self):
        intf = self.getInterface("systemd")
        f = getattr(intf, "StartUnit")
        f.call_async("obmc-host-quiesce@0.target", "replace")
        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 power_button_signal_handler(self):
        # toggle power, power-on / soft-power-off
        state = self.getPowerState()
        if state == POWER_OFF:
            self.powerOn()
        elif state == POWER_ON:
            self.softPowerOff()

    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, Going to quiesce")
        self.quiesce()


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

    bus = get_dbus()
    obj = ChassisControlObject(bus, OBJ_NAME)
    mainloop = gobject.MainLoop()

    obj.unmask_signals()
    name = dbus.service.BusName(DBUS_NAME, bus)

    print("Running ChassisControlService")
    mainloop.run()

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
