#!/usr/bin/python3
#
# Copyright (C) 2014-2016 Canonical Ltd.
# Copyright (C) 2021 Ratchanan Srirattanamet <ratchanan@ubports.com>
# Copyright (C) 2022-2024 Guido Berhoerster <guido+ubports@berhoerster.name>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""Populate notification settings from installed packages."""

import argparse
import json
import logging
from pathlib import Path

import gi
from gi.repository import GLib
from gi.repository import Gio


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():
    logging.debug(f"populating notification settings...")

    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 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__":
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("-D", "--debug",
                        help="Enable debug logging",
                        action="store_true",
                        default=False)
    args = parser.parse_args()
    if args.debug:
        logging.getLogger().setLevel(logging.DEBUG)

    populate_notifications_settings()
