# -*- 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
from typing import AnyStr

# External libraries
import tblock
from tblock.utils import is_valid_ip
import tblock.exceptions

# Local libraries
from .const import ExitStatusCode
from ._polkit import pk_subprocess_run, pk_dummy_authenticate

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


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

    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("RuleAddActivity")
        self.window.set_application(self._application)

        self._policy = None

    def start(self) -> None:
        """
        Start the dialog to add a new rule
        """
        # Set the default policy to BLOCK
        self._application.builder.get_object("RulePolicyBlock").set_active(True)
        self.select_policy(tblock.BLOCK)
        # Clear previously entered values
        self._application.builder.get_object("RuleAddActivityDomainField").set_text("")
        self._application.builder.get_object("RuleAddActivityRedirectIPField").set_text(
            ""
        )
        # Start the activity
        self.window.run()
        self.window.resize(100, 100)
        self.window.hide()

    def select_policy(self, policy: AnyStr) -> None:
        """
        Select the policy to use when adding rule

        :param policy: Either "tblock.ALLOW", "tblock.BLOCK" or "tblock.REDIRECT"
        """
        redirect_field = self._application.builder.get_object(
            "RuleAddActivityRedirectField"
        )
        self._policy = policy
        if self._policy == tblock.REDIRECT:
            redirect_field.show()
        else:
            redirect_field.hide()
        self.window.resize(100, 100)

    def run(self) -> None:
        """
        Launch the process to add the rule
        """
        domain_field = self._application.builder.get_object(
            "RuleAddActivityDomainField"
        )
        redirect_ip_field = self._application.builder.get_object(
            "RuleAddActivityRedirectIPField"
        )
        _auth_err_code = pk_dummy_authenticate()
        if _auth_err_code == ExitStatusCode.NO_ERROR:
            if tblock.utils.db_is_locked():
                self._application.error_window.raise_db_locked_error()
            elif not domain_field.get_text():
                self._application.error_window.raise_error(
                    _("Please specify a valid domain")
                )
            else:
                if self._policy == tblock.ALLOW:
                    if (
                        pk_subprocess_run(["allow", domain_field.get_text()])
                        != ExitStatusCode.NO_ERROR
                    ):
                        self._application.error_window.raise_error(
                            _("Failed to allow domain: {}").format(
                                domain_field.get_text()
                            )
                        )
                elif self._policy == tblock.BLOCK:
                    if (
                        pk_subprocess_run(["block", domain_field.get_text()])
                        != ExitStatusCode.NO_ERROR
                    ):
                        self._application.error_window.raise_error(
                            _("Failed to block domain: {}").format(
                                domain_field.get_text()
                            )
                        )
                elif self._policy == tblock.REDIRECT and is_valid_ip(
                    redirect_ip_field.get_text()
                ):
                    if (
                        pk_subprocess_run(
                            [
                                "redirect",
                                domain_field.get_text(),
                                redirect_ip_field.get_text(),
                            ]
                        )
                        != ExitStatusCode.NO_ERROR
                    ):
                        self._application.error_window.raise_error(
                            _("Failed to redirect domain: {}").format(
                                domain_field.get_text()
                            )
                        )
                else:
                    self._application.error_window.raise_error(
                        _("Please specify a valid IP address.")
                    )
                self.quit()
        else:
            self._application.error_window.handle_error(_auth_err_code)

    def quit(self) -> None:
        """
        Quit the activity
        """
        self.window.hide()
