#!/usr/bin/python3

import gettext
import locale
import logging
import threading
import time

import dbus
import dbus.mainloop.glib
import dbus.service
from gi.repository import GLib

from yumex.constants import BACKEND, LOCALEDIR
from yumex.service.data import Config, Indicator, Updates, open_yumex
from yumex.service.notification import Action, Notification

gettext.install("yumex", LOCALEDIR)
locale.bindtextdomain("yumex", LOCALEDIR)
locale.textdomain("yumex")

# Setup logger
logger = logging.getLogger("yumex_updater")
logging.basicConfig(
    level=logging.DEBUG,
    format="(%(name)-5s) -  %(message)s",
    datefmt="%H:%M:%S",
)

UPDATER_BUS_NAME = "dk.yumex.UpdateService"
UPDATER_OBJECT_PATH = "/" + UPDATER_BUS_NAME.replace(".", "/")


class UpdateService(dbus.service.Object):
    @dbus.service.method(dbus_interface=UPDATER_BUS_NAME, in_signature="b", out_signature="")
    def RefreshUpdates(self, refresh: bool) -> None:
        logger.debug(f"DBUS: RefreshUpdates {refresh}")
        GLib.idle_add(refresh_updates, refresh)


def refresh_updates(refresh: bool) -> None:
    """check for new updates"""
    logger.debug(f"Refreshing updates ({refresh})")
    updates: Updates = Updates.get_updates(refresh)

    update_count = updates.sys_update_count + updates.flatpak_user_count + updates.flatpak_sys_count

    logger.debug(f" --> flatpak system : {updates.flatpak_sys_count}")
    logger.debug(f" --> flatpak user   : {updates.flatpak_user_count}")
    logger.debug(f" --> {BACKEND}   : {updates.sys_update_count}")

    hover_text_lines = ["There are updates available:"]
    noti_body = ""
    if updates.sys_update_count > 0:
        hover_text_lines.append(f"  System: {updates.sys_update_count}")
        noti_body += f"{updates.sys_update_count} package(s). "
    if updates.flatpak_user_count > 0:
        hover_text_lines.append(f"  Flatpak (user): {updates.flatpak_user_count}")
        noti_body += f"{updates.flatpak_user_count} flatpak(s) (user). "
    if updates.flatpak_sys_count > 0:
        hover_text_lines.append(f"  Flatpak (system): {updates.flatpak_sys_count}")
        noti_body += f"{updates.flatpak_sys_count} flatpak(s) (system). "
    hover_text = "\n".join(hover_text_lines)
    if CONFIG.show_icon:
        if update_count > 0:
            GLib.idle_add(INDICATOR.set_title, hover_text)
            INDICATOR.last_flatpaks = updates.flatpak_user_count + updates.flatpak_sys_count
            INDICATOR.last_pkgs = updates.sys_update_count
        else:
            INDICATOR.clear()

    if CONFIG.send_notification:
        logger.debug(f"Notification : {update_count=} {NOTIFICATION.last_value=} ")
        if update_count > 0 and update_count != NOTIFICATION.last_value:
            summary = _("Updates are available")
            body = noti_body
            NOTIFICATION.send(summary, body)
            NOTIFICATION.last_value = update_count
            NOTIFICATION.last_pkgs = updates.sys_update_count
            NOTIFICATION.last_flatpaks = updates.flatpak_user_count + updates.flatpak_sys_count


def check_updates() -> None:
    """Main thread function for checking for new updates at a given time periode"""
    while True:
        refresh_updates(False)
        time.sleep(CONFIG.update_sync_interval)


def setup_notification():
    """Setup the notifier class"""
    app_name = "Yum Extender"
    icon_name = "software-update-available-symbolic"
    # action to show in notification
    actions = [Action(id="open-yumex", title="Open Yum Extender", callback=open_yumex)]
    notification = Notification(app_name, icon_name, actions=actions)
    return notification


# Setup Global Constants
CONFIG = Config.from_gsettings()
INDICATOR = Indicator(custom_updater=CONFIG.custom_updater, refresh_func=refresh_updates, dark_icon=CONFIG.dark_icon)

if CONFIG.send_notification:
    NOTIFICATION: Notification = setup_notification()
else:
    NOTIFICATION = None


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

    session_bus = dbus.SessionBus()
    name = dbus.service.BusName(UPDATER_BUS_NAME, session_bus)  # noqa: F841
    obj = UpdateService(session_bus, UPDATER_OBJECT_PATH)  # noqa: F841

    # Setup scheduled update check
    update_thread = threading.Thread(target=check_updates, daemon=True)
    update_thread.start()
    loop = GLib.MainLoop()
    loop.run()


if __name__ == "__main__":
    main()
