#!/usr/bin/python3
# -*- python -*-
"""Populate notification settings from installed packages."""

import argparse
import json
import logging
from pathlib import Path

import xdg.BaseDirectory

import gi
gi.require_version("Click", "0.4")
from gi.repository import GLib
from gi.repository import Gio
from gi.repository import Click


def populate_settings_from_legacy_dpkg():
    legacy_helpers_path = Path("/usr/lib/lomiri-push-service/legacy-helpers/")

    if not legacy_helpers_path.is_dir():
        return []

    dpkg_apps_keys = []
    for f in legacy_helpers_path.iterdir():
        if f.is_file():
            dpkg_apps_keys.append("/".join(["dpkg", f.name, "0"]))
            logging.debug(f"adding notification setting for app {f.name}")
    return dpkg_apps_keys


def reset_settings(path=None):
    if not path:
        return

    logging.debug(
        f'resetting notification setting for removed application "{path}"'
    )
    settings_path = f"/com/lomiri/NotificationSettings/{path}/"
    try:
        settings = Gio.Settings.new_with_path(
            "com.lomiri.notifications.settings", settings_path
        )
        for k in settings.list_keys():
            settings.reset(k)
    except Exception as e:
        logging.warning(f"failed to reset settings: {e}")


def reset_removed_applications(current_apps=None, new_apps=None):
    if not current_apps or not new_apps:
        return

    current_keys = ["/".join(k.split("/")[:2]) for k in current_apps]
    new_keys = ["/".join(k.split("/")[:2]) for k in new_apps]
    for settings_path in set(current_keys) - set(new_keys):
        reset_settings(settings_path)


def populate_notifications_settings(hooks_path):
    logging.debug(f"populating notification settings...")
    if not hooks_path or not Path(hooks_path).is_dir():
        return

    db = Click.DB.new()
    db.read()

    settings = Gio.Settings.new(
        "com.lomiri.notifications.settings.applications"
    )
    applications = GLib.VariantBuilder.new(GLib.VariantType.new("as"))

    current_applications_keys = settings.get_value("applications").unpack()

    applications_keys = populate_settings_from_legacy_dpkg()
    for hook in Path(hooks_path).iterdir():
        pkg_name, helper_name, version = hook.stem.split("_")

        manifest = json.loads(db.get_manifest_as_string(pkg_name, version))
        hooks = manifest.get("hooks", None)
        if not hooks:
            continue

        app_names = [h for h in hooks.keys() if "desktop" in hooks[h].keys()]

        for app_name in app_names:
            app_key = "/".join([pkg_name, app_name, version])
            logging.debug(f"adding notification setting for app {app_key}")
            applications_keys.append(app_key)

    for app_key in applications_keys:
        applications.add_value(GLib.Variant.new_string(app_key))

    settings.set_value("applications", applications.end())

    reset_removed_applications(current_applications_keys, applications_keys)


if __name__ == "__main__":
    xdg_data_home = xdg.BaseDirectory.xdg_data_home

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("-D", "--debug",
                        help="Enable debug logging",
                        action="store_true",
                        default=False)
    parser.add_argument("-d", "--data-home",
                        help="The Path to the (xdg) data home",
                        default=xdg_data_home)
    args = parser.parse_args()
    if args.debug:
        logging.getLogger().setLevel(logging.DEBUG)
    hooks_path = Path(args.data_home) / "lomiri-push-service" / "helpers"

    populate_notifications_settings(hooks_path)
