# -*- coding: utf-8 -*-
#  _____  ____   _               _
# |_   _|| __ ) | |  ___    ___ | | __
#   | |  |  _ \ | | / _ \  / __|| |/ /
#   | |  | |_) || || (_) || (__ |   <
#   |_|  |____/ |_| \___/  \___||_|\_\
#
# Copyright (C) 2021-2025 Camelia Lavender <camelia@tblock.me>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY 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 <https://www.gnu.org/licenses/>.

# Standard libraries
import gettext

# External libraries
import tblock
import tblock.style
import gi

# Local libraries
from ._polkit import pk_dummy_authenticate, pk_subprocess_run
from .utils import get_human_readable
from .const import PATH_GUI, ExitStatusCode
from .config import get_setting, update_available, GUISettings

gi.require_version("Gtk", "3.0")
# pylint: disable=wrong-import-position,wrong-import-order
from gi.repository import Gtk, GLib

gettext.textdomain("tblock-gui")
_ = gettext.gettext


class MainActivity:
    """
    Class that interacts with the activity of the same name from the glade UI
    """

    # pylint: disable=too-many-instance-attributes

    def __init__(self, application) -> None:
        """
        Initiate the activity

        :param application: An object of type Gtk.Application
        """
        self._application = application
        self.window = self._application.builder.get_object("MainActivity")
        self.window.set_application(self._application)
        self.running = False
        self.status_icon = self._application.builder.get_object("StatusImage")
        self.status_title = self._application.builder.get_object("StatusText")
        self.status_desc = self._application.builder.get_object(
            "MainActivityStatsLabel"
        )
        self.status_button = self._application.builder.get_object("StatusToggleButton")

    def start(self) -> None:
        """
        Start the main activity
        """
        self.window.connect("destroy", Gtk.main_quit)
        self.window.show_all()
        self.refresh()
        self._application.builder.get_object("UpdaterButton").hide()
        if get_setting(GUISettings.UPDATE_STARTUP_CHECK.value):
            GLib.timeout_add(200, self.look_for_updates)

    def refresh(self) -> None:
        """
        Refresh the activity
        """
        if tblock.config.hosts_are_default():
            self.status_icon.set_from_file(PATH_GUI.DISABLED_IMAGE)
            self.status_button.set_label(_("Enable"))
            self.status_title.set_label(_("Protection is inactive"))
            self.status_desc.set_text(_("Enable protection to show statistics"))
        elif tblock.style.hosts_are_safe():
            self.status_icon.set_from_file(PATH_GUI.ENABLED_IMAGE)
            self.status_button.set_label(_("Disable"))
            self.status_title.set_label(_("Protection is active"))
            self.status_desc.set_text(
                _("{0} filter list(s) enabled and {1} active rule(s)").format(
                    tblock.get_active_filter_lists_count(),
                    get_human_readable(tblock.get_rules_count()),
                )
            )
        else:
            self.status_icon.set_from_file(PATH_GUI.THREAT_IMAGE)
            self.status_button.set_label(_("Repair"))
            self.status_title.set_label(_("Threat detected"))
            self.status_desc.set_text(_("Your secure network may not be safe anymore"))

    def look_for_updates(self) -> None:
        """
        Refresh updater widget to indicate whether an update is available
        :return:
        """
        label = self._application.builder.get_object("UpdaterActivityLabel")
        link = self._application.builder.get_object("UpdaterActivityLink")
        button = self._application.builder.get_object("UpdaterButton")
        icon = self._application.builder.get_object("UpdaterIcon")
        if update_available():
            label.set_label(_("An update is available!"))
            link.show()
            icon.set_opacity(1)
        else:
            label.set_label(_("No update available"))
            link.hide()
            icon.set_opacity(0.5)
        button.show()

    def run(self) -> None:
        """
        Run the operation to either disable/enable the protection
        """
        _auth_err_code = pk_dummy_authenticate()
        if _auth_err_code == ExitStatusCode.NO_ERROR:
            if not self.running:
                self.running = True
                if tblock.config.hosts_are_default():
                    if pk_subprocess_run(["enable"]) != ExitStatusCode.NO_ERROR:
                        if pk_subprocess_run(["build"]) != ExitStatusCode.NO_ERROR:
                            self._application.error_window.raise_error(
                                _(
                                    "Failed to enable protection and to build new hosts file."
                                )
                            )
                elif tblock.style.hosts_are_safe():
                    if pk_subprocess_run(["disable"]) != ExitStatusCode.NO_ERROR:
                        self._application.error_window.raise_error(
                            _("Failed to disable protection.")
                        )
                else:
                    if pk_subprocess_run(["build"]) != ExitStatusCode.NO_ERROR:
                        self._application.error_window.raise_error(
                            _("Failed to build hosts file.")
                        )
                self.refresh()
                self.running = False
        else:
            self._application.error_window.handle_error(_auth_err_code)

    def quit(self) -> None:
        """
        Quit the activity & the application
        """
        self._application.quit()
