import os
import sys

import dbus
import dbus.mainloop.glib
import dbus.service
# "pip3 install dbus-python" on Linux
import gi.repository.GLib

import ipc_common
import ipc_svcobj


def stop_server():
    try:
        proxy_object = dbus.SystemBus().get_object(ipc_common.SERVICE_BUS, ipc_common.SERVICE_OBJECT_PATH)
        proxy_object.quit()
    except dbus.DBusException as e:
        if e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown':
            print('IPC Service is not running')
        else:
            print('IPC Service exception:', e._dbus_error_name)


def start_server(debug_mode: bool, gpio_enabled: bool):
    if os.getuid() != 0:
        sys.exit('IPC Service must be run under root privileges.')

    fsstat = os.statvfs('/')				#Get the mountpoint info of the root fs
    ST_RDONLY = 1
    ismounted_ro = bool(fsstat.f_flag & os.ST_RDONLY)
    if ismounted_ro == True:
        os.system('mount -o remount,rw /dev/mmcblk0 /')	#System boots with rootfs in RO, we must remount to RW. After this the FS is protection by the powerfailure detection
        print('RO filesystem detected, remounted to RW')
    else:
        print('RW filesystem detected, proceeding')

    apachestat = os.system('systemctl status apache2')
    if apachestat == 0:
        print('Apache2 is already running')
    else:
        os.system('systemctl restart apache2.service')	# This is a ugly workaround, apache2 serivce doesn't start in a RO filesystem, so we must restart it after the FS is remounted in RW. Relying apache service on givaipc service didn't work.
        print('Apache2 not running, restarting apache2 service')

    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    system_bus = dbus.SystemBus()
    try:
        # Export the object across the bus
        name = dbus.service.BusName(ipc_common.SERVICE_BUS, system_bus, do_not_queue=True)
    except dbus.NameExistsException:
        sys.exit('IPC Service is already running.')

    print('IPC Service started:', name.get_name())

    mainloop = gi.repository.GLib.MainLoop()
    service_object = ipc_svcobj.ServiceObject(system_bus, ipc_common.SERVICE_OBJECT_PATH, debug_mode, gpio_enabled)
    service_object.mainloop = mainloop
    mainloop.run()


def main(exe, args):
    if sys.version_info[0] < 3:
        sys.exit("Must run using Python 3 or newer.")

    gpio_enabled = True
    if '--no-gpio' in args:
        gpio_enabled = False

    if 'start' in args:
        start_server(debug_mode=False, gpio_enabled=gpio_enabled)
    elif 'startdebug' in args:
        start_server(debug_mode=True, gpio_enabled=gpio_enabled)
    elif 'stop' in args:
        stop_server()
    else:
        sys.exit('Usage: %s start|startdebug|stop [--no-gpio]' % exe)


if __name__ == '__main__':
    main(sys.argv[0], sys.argv[1:])
