"""
Firewall rule model for network security rules.

Firewall rules track network security rules for documentation and audit trail
purposes, including source/destination CIDRs, ports, protocols, and actions.
"""

from typing import Optional

from sqlalchemy import CHAR, CheckConstraint, ForeignKey, Index, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column

from .base import Base, TimestampMixin, UUIDMixin


class FirewallRule(Base, UUIDMixin, TimestampMixin):
    """
    Firewall rule model for network security rules.

    Tracks firewall rules for documentation and audit trail purposes,
    including source and destination CIDRs, ports, protocols, and
    allow/deny/drop actions.

    Attributes:
        infrastructure_id: Reference to the infrastructure this rule applies to
        rule_name: Name of the firewall rule
        source_cidr: Source CIDR notation
        destination_cidr: Destination CIDR notation
        port: Port number
        protocol: Protocol (tcp, udp, icmp)
        action: Action to take (allow, deny, drop)
        rule_order: Order of the rule in the firewall
        notes: Additional notes
        created_at: When the rule was created
        created_by: Who created the rule
    """

    __tablename__ = "firewall_rules"

    # Foreign keys
    infrastructure_id: Mapped[Optional[str]] = mapped_column(
        CHAR(36),
        ForeignKey("infrastructure.id", ondelete="CASCADE"),
        doc="Reference to the infrastructure this rule applies to"
    )

    # Rule identification
    rule_name: Mapped[Optional[str]] = mapped_column(
        String(255),
        doc="Name of the firewall rule"
    )

    # Rule configuration
    source_cidr: Mapped[Optional[str]] = mapped_column(
        String(100),
        doc="Source CIDR notation"
    )

    destination_cidr: Mapped[Optional[str]] = mapped_column(
        String(100),
        doc="Destination CIDR notation"
    )

    port: Mapped[Optional[int]] = mapped_column(
        Integer,
        doc="Port number"
    )

    protocol: Mapped[Optional[str]] = mapped_column(
        String(20),
        doc="Protocol: tcp, udp, icmp"
    )

    action: Mapped[Optional[str]] = mapped_column(
        String(20),
        doc="Action: allow, deny, drop"
    )

    # Rule ordering
    rule_order: Mapped[Optional[int]] = mapped_column(
        Integer,
        doc="Order of the rule in the firewall"
    )

    # Notes
    notes: Mapped[Optional[str]] = mapped_column(
        Text,
        doc="Additional notes"
    )

    # Audit information
    created_by: Mapped[Optional[str]] = mapped_column(
        String(255),
        doc="Who created the rule"
    )

    # Constraints and indexes
    __table_args__ = (
        CheckConstraint(
            "action IN ('allow', 'deny', 'drop')",
            name="ck_firewall_rules_action"
        ),
        Index("idx_firewall_infra", "infrastructure_id"),
    )

    def __repr__(self) -> str:
        """String representation of the firewall rule."""
        return f"<FirewallRule(rule_name='{self.rule_name}', action='{self.action}')>"
