"""Types for ..rules package.

Introduced to avoid circular imports.
"""
from abc import ABCMeta, abstractmethod
from dataclasses import dataclass
from typing import Mapping, Iterator, AbstractSet

from im360.internals.core.firewall import FirewallRules, RuleDef
from defence360agent.utils.validate import IPVersion


@dataclass(frozen=True)  # TODO set kw_only=True in 3.10
class FirewallRule:
    rule: RuleDef

    #: iptables table name where to put the rule
    #:   such as "filter", "nat", "mangle"
    #:   note: no "raw", "security" tables
    table: str = FirewallRules.FILTER
    #: iptables chain name (when rule is active)
    chain: str = FirewallRules.IMUNIFY_INPUT_CHAIN
    #: priority (relative position in the chain)
    priority: int = FirewallRules.DEFAULT_PRIORITY


class WebshieldRuleBuilder(metaclass=ABCMeta):
    """Base class to define steps necessary to implement webshield-related
      iptables rule generation.

    Known subclasses: SplashscreenRuleBuilder, CaptchaRuleBuilder

    """

    @abstractmethod
    def open_webshield_ports_for_localhost_rules(
        self,
        ip_version: IPVersion,
    ) -> Iterator[FirewallRule]:
        pass

    @abstractmethod
    def block_webshield_ports_rules(
        self, redirect_map: Mapping[int, int], dest_ports: AbstractSet
    ) -> Iterator[FirewallRule]:
        pass

    @abstractmethod
    def redirect_panel_ports(
        self, ip_version: IPVersion
    ) -> Iterator[FirewallRule]:
        pass

    @abstractmethod
    def logdrop_chain_rules(self, ipset_name: str) -> Iterator[FirewallRule]:
        pass

    @abstractmethod
    def drop_tproxy_rules(self, ipset_name: str) -> Iterator[FirewallRule]:
        pass
