"""CyberScanner and CyberLabel enum for meshulash-guard SDK.

CyberScanner detects and acts on text containing cyber security threats
categorized by the server's 'cysecbench' TC classification head. Label values
are the exact strings from the server's label_config.json (case-sensitive).
"""

from __future__ import annotations

from typing import Sequence

from ..enums import Action, Condition, _StrValueMixin
from .base import BaseScanner


class CyberLabel(_StrValueMixin):
    """Labels for cyber security threat detection.

    Values are the exact strings used by the server's 'cysecbench' TC head.
    Member names are uppercase/underscored for Python ergonomics.
    """

    CLOUD_ATTACKS = "Cloud Attacks"
    CONTROL_SYSTEM_ATTACKS = "Control System Attacks"
    CRYPTOGRAPHIC_ATTACKS = "Cryptographic Attacks"
    EVASION_TECHNIQUES = "Evasion Techniques"
    HARDWARE_ATTACKS = "Hardware Attacks"
    INTRUSION_TECHNIQUES = "Intrusion Techniques"
    IOT_ATTACKS = "IoT Attacks"
    MALWARE_ATTACKS = "Malware Attacks"
    NETWORK_ATTACKS = "Network Attacks"
    NONE = "None"
    WEB_APPLICATION_ATTACKS = "Web Application Attacks"
    ALL = "__ALL__"


class CyberScanner(BaseScanner):
    """Scanner for cyber security threat detection.

    Detects text related to cyber attacks and security threats using the
    server's 'cysecbench' TC classification head.

    Args:
        labels: One or more CyberLabel members. Use CyberLabel.ALL to scan
            all cyber threat categories. Cannot be empty.
        action: Action to take when a cyber threat is detected. Defaults to BLOCK.
        condition: Gating condition (ANY, ALL, K_OF, CONTEXTUAL).
        threshold: Optional confidence threshold (0.0–1.0).
        allowlist: Optional list of values to allow through even if detected.
    """

    _TC_HEAD = "cysecbench"

    def __init__(
        self,
        labels: Sequence[CyberLabel],
        action: Action = Action.BLOCK,
        condition: Condition = Condition.ANY,
        threshold: float | None = None,
        allowlist: list[str] | None = None,
    ) -> None:
        if not labels:
            raise ValueError(
                "CyberScanner requires at least one label. "
                "Use CyberLabel.ALL to scan everything."
            )
        self._labels = list(labels)
        self._action = action
        self._condition = condition
        self._threshold = threshold
        self._allowlist = allowlist or []

    def to_guardline_spec(self) -> dict:
        """Return a guardline spec dict for this scanner configuration."""
        if any(lbl.value == "__ALL__" for lbl in self._labels):
            all_labels = [m for m in type(self._labels[0]) if m.value != "__ALL__"]
        else:
            all_labels = self._labels
        tc_pairs = [[self._TC_HEAD, lbl.value] for lbl in all_labels]
        spec: dict = {
            "name": self.__class__.__name__,
            "condition": str(self._condition),
            "action": str(self._action),
            "level": 2,
            "types": {"regex": False, "ner": False, "tc": True},
            "required": {"regex": [], "ner": [], "tc": tc_pairs},
            "allowlist": list(self._allowlist),
            "bundles": [],
            "k": 0,
        }
        if self._threshold is not None:
            spec["threshold"] = self._threshold
        return spec
