# #region AuthLoggerModule [C:5] [TYPE Module] [SEMANTICS auth, audit, logging]
#
# @BRIEF Structured auth logging module for audit trail generation.
# @LAYER Core
# @RELATION DEPENDS_ON -> [EXT:frontend:core_logger]
#
# @INVARIANT  Must not log sensitive data like passwords or full tokens.
#            Sensitive field names (password, secret, token, key, authorization)
#            in the details dict are automatically masked.
# @PRE  Auth module initialized
# @POST  Audit logging functions exported
# @SIDE_EFFECT  Writes auth audit log entries
# @DATA_CONTRACT  AuthEvent -> LogEntry

from datetime import UTC, datetime
import re
from typing import Any

from ..logger import belief_scope, logger

# Sensitive field name patterns — values for these keys are masked in logs
_SENSITIVE_KEYS = re.compile(
    r"^(password|secret|token|api_key|api\.key|authorization|auth|credential|credit_card|ssn)$",
    re.IGNORECASE,
)


def _mask_details(details: dict[str, Any] | None) -> dict[str, Any] | None:
    """Return a copy of details with sensitive field values replaced by '***'."""
    if not details:
        return details
    masked = {}
    for key, value in details.items():
        if isinstance(key, str) and _SENSITIVE_KEYS.match(key):
            masked[key] = "***"
        elif isinstance(value, dict):
            masked[key] = _mask_details(value)
        else:
            masked[key] = value
    return masked


# #region log_security_event [TYPE Function]
# @BRIEF Logs a security-related event for audit trails.
# @PRE      event_type and username are strings.
# @POST     Security event is written to the application log via %s-formatting to prevent log injection.
#          Sensitive fields in details dict are masked.
# @RELATION DEPENDS_ON -> [logger]
# @RATIONALE Uses %s-formatting (not f-strings) to prevent log forging via CRLF injection in
#            user-controlled fields — see [SEC:H-1]. Sensitive fields in details
#            dict are masked to prevent credential leakage — see [SEC:L-1].
def log_security_event(event_type: str, username: str, details: dict = None):
    with belief_scope("log_security_event", f"{event_type}:{username}"):
        timestamp = datetime.now(UTC).isoformat()
        logger.info(
            "[AUDIT][%s][%s] User: %s",
            timestamp,
            event_type,
            username,
        )
        safe_details = _mask_details(details)
        if safe_details:
            logger.info(
                "[AUDIT][%s][%s] Details: %s",
                timestamp,
                event_type,
                safe_details,
            )
# #endregion log_security_event

# #endregion AuthLoggerModule
