"""Vulnerability manager composing all mixins.

Coordinates evaluation across protocols/modes and writes results to CSV.
"""
from __future__ import annotations

from ptnetinspector.send.send import IPMode
from ptnetinspector.utils.ip_utils import convert_preferenceRA
from ptnetinspector.utils.path import get_csv_path

from ptnetinspector.vulnerability.base import VulnerabilityBase
from ptnetinspector.vulnerability.eap import EAPMixin
from ptnetinspector.vulnerability.mdns import MDNSMixin
from ptnetinspector.vulnerability.llmnr import LLMNRMixin
from ptnetinspector.vulnerability.ws import WSMixin
from ptnetinspector.vulnerability.mld import MLDMixin
from ptnetinspector.vulnerability.ipv6 import IPv6PredictableMixin
from ptnetinspector.vulnerability.icmp import ICMPMixin
from ptnetinspector.vulnerability.ra import RAMixin


class Vulnerability(
    VulnerabilityBase,
    EAPMixin,
    MDNSMixin,
    LLMNRMixin,
    WSMixin,
    MLDMixin,
    IPv6PredictableMixin,
    ICMPMixin,
    RAMixin,
):
    def __init__(
        self,
        interface: str,
        mode: list[str],
        ipver: IPMode,
        smac: str,
        network: str,
        prefix_len: int,
        rpref: int,
        dns: list[str],
        role_file: str | None = None,
        time_incoming_file: str | None = None,
        time_all_file: str | None = None,
        vulnerability_file: str | None = None,
        target_codes: set[str] | None = None,
        target_macs: set[str] | None = None,
    ) -> None:
        pref = convert_preferenceRA(rpref)
        super().__init__(
            interface,
            mode,
            ipver,
            smac,
            network,
            prefix_len,
            pref,
            dns,
            role_file=role_file or get_csv_path("role_node.csv"),
            time_incoming_file=time_incoming_file or get_csv_path("time_incoming.csv"),
            time_all_file=time_all_file or get_csv_path("time_all.csv"),
            vulnerability_file=vulnerability_file or get_csv_path("vulnerability.csv"),
            target_codes=target_codes,
            target_macs=target_macs,
        )

    def handle_vulnerabilities(self, specific_mode: str) -> None:
        """Evaluate and persist vulnerabilities for the given mode.

        Args:
            specific_mode: One of "802.1x", "p", "a", "a+".
        """
        if specific_mode == "802.1x":
            self.store_eap_vulnerability()
        if specific_mode in ["p", "a", "a+"]:
            self.store_MDNS_vulnerability()
            self.store_llmnr_vulnerability()
            self.store_ws_vulnerability()
            self.store_icmp_vulnerability()
            if getattr(self.ipver, "ipv6", False):
                self.store_mld_vulnerability()
                self.store_ipv6_vulnerability()
        if specific_mode == "a+" and getattr(self.ipver, "ipv6", False):
            self.store_ra_vulnerability()

        self.sort_and_dedupe(self.vulnerability_file)
        self._prune_vulnerability_file()
        self._filter_by_target_macs()
