"""Jail domain models.

Internal domain-focused models used by jail_service. These represent the
business domain layer and are independent of HTTP response shapes.

Response models are defined in `app.models.jail` and mappers convert domain
models to response models at the router boundary.
"""

from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class DomainJailStatus:
    """Runtime metrics for a single jail (domain model)."""

    currently_banned: int
    total_banned: int
    currently_failed: int
    total_failed: int


@dataclass(frozen=True)
class DomainBantimeEscalation:
    """Incremental ban-time escalation configuration (domain model)."""

    increment: bool = False
    factor: float | None = None
    formula: str | None = None
    multipliers: str | None = None
    max_time: int | None = None
    rnd_time: int | None = None
    overall_jails: bool = False


@dataclass(frozen=True)
class DomainJailSummary:
    """Lightweight jail entry for the overview list (domain model)."""

    name: str
    enabled: bool
    running: bool
    idle: bool
    backend: str
    find_time: int
    ban_time: int
    max_retry: int
    status: DomainJailStatus | None = None


@dataclass(frozen=True)
class DomainJailList:
    """List of active jails (domain model)."""

    items: list[DomainJailSummary]
    total: int


@dataclass(frozen=True)
class DomainJail:
    """Full jail configuration (domain model)."""

    name: str
    enabled: bool
    running: bool
    idle: bool
    backend: str
    log_paths: list[str]
    fail_regex: list[str]
    ignore_regex: list[str]
    ignore_ips: list[str]
    find_time: int
    ban_time: int
    max_retry: int
    actions: list[str]
    date_pattern: str | None = None
    log_encoding: str = "UTF-8"
    bantime_escalation: DomainBantimeEscalation | None = None
    status: DomainJailStatus | None = None


@dataclass(frozen=True)
class DomainActiveBan:
    """A currently active ban entry from a jail (domain model)."""

    ip: str
    jail: str
    banned_at: str | None = None
    expires_at: str | None = None
    ban_count: int = 1
    country: str | None = None


@dataclass(frozen=True)
class DomainJailBannedIps:
    """Paginated list of currently banned IPs for a jail (domain model)."""

    items: list[DomainActiveBan]
    total: int
    page: int
    page_size: int


@dataclass(frozen=True)
class DomainJailDetail:
    """Full jail with supplemental metadata (domain model)."""

    jail: DomainJail
    ignore_list: list[str]
    ignore_self: bool
