"""Utilities for ensuring required fail2ban jail configuration files exist.

BanGUI requires two custom jails — ``manual-Jail`` and ``blocklist-import``
— to be present in the fail2ban ``jail.d`` directory.  This module provides
:func:`ensure_jail_configs` which checks each of the four files
(``*.conf`` template + ``*.local`` override) and creates any that are missing
with the correct default content.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import structlog

if TYPE_CHECKING:
    from pathlib import Path

log: structlog.stdlib.BoundLogger = structlog.get_logger()

# ---------------------------------------------------------------------------
# Default file contents
# ---------------------------------------------------------------------------

_MANUAL_JAIL_CONF = """\
[manual-Jail]

enabled    = false
filter     = manual-Jail
logpath    = /remotelogs/bangui/auth.log
backend    = polling
maxretry   = 3
findtime   = 120
bantime    = 60
ignoreip   = 127.0.0.0/8 ::1 172.16.0.0/12
"""

_MANUAL_JAIL_LOCAL = """\
[manual-Jail]
enabled    = true
"""

_BLOCKLIST_IMPORT_CONF = """\
[blocklist-import]

enabled    = false
filter     =
logpath    = /dev/null
backend    = auto
maxretry   = 1
findtime   = 1d
bantime    = 86400
ignoreip   = 127.0.0.0/8 ::1 172.16.0.0/12
"""

_BLOCKLIST_IMPORT_LOCAL = """\
[blocklist-import]
enabled    = true
"""

# ---------------------------------------------------------------------------
# File registry: (filename, default_content)
# ---------------------------------------------------------------------------

_JAIL_FILES: list[tuple[str, str]] = [
    ("manual-Jail.conf", _MANUAL_JAIL_CONF),
    ("manual-Jail.local", _MANUAL_JAIL_LOCAL),
    ("blocklist-import.conf", _BLOCKLIST_IMPORT_CONF),
    ("blocklist-import.local", _BLOCKLIST_IMPORT_LOCAL),
]


def ensure_jail_configs(jail_d_path: Path) -> None:
    """Ensure the required fail2ban jail configuration files exist.

    Checks for ``manual-Jail.conf``, ``manual-Jail.local``,
    ``blocklist-import.conf``, and ``blocklist-import.local`` inside
    *jail_d_path*.  Any file that is missing is created with its default
    content.  Existing files are **never** overwritten.

    Args:
        jail_d_path: Path to the fail2ban ``jail.d`` directory.  Will be
            created (including all parents) if it does not already exist.
    """
    jail_d_path.mkdir(parents=True, exist_ok=True)

    for filename, default_content in _JAIL_FILES:
        file_path = jail_d_path / filename
        if file_path.exists():
            log.debug("jail_config_already_exists", path=str(file_path))
        else:
            file_path.write_text(default_content, encoding="utf-8")
            log.info("jail_config_created", path=str(file_path))
