"""
Limites de peticiones.

Los endpoints de envio gastan dinero: cada SMS y cada mensaje de WhatsApp se
factura, y el correo consume la reputacion del dominio. Una credencial robada
sin limite de velocidad se convierte en una plataforma de spam a cargo de la
empresa antes de que nadie se de cuenta.
"""

from __future__ import annotations

from rest_framework.throttling import SimpleRateThrottle

from core.utils.http import get_client_ip


class SendThrottle(SimpleRateThrottle):
    """
    Limita los envios por cuenta, con el usuario y la IP como respaldo.

    Contaba por `request.user.pk`, y `Account.user` es una clave ajena al
    usuario de Django: dos cuentas distintas —clientes distintos, con claves
    distintas y con sus datos aislados entre si— pueden colgar del mismo
    usuario y compartir cupo. Uno agotaba el limite del otro.
    """

    scope = "send"

    def get_cache_key(self, request, view):
        clave = getattr(request, "api_key_record", None)
        if clave is not None:
            ident = f"account:{clave.account_id}"
        elif request.user and request.user.is_authenticated:
            ident = f"user:{request.user.pk}"
        else:
            ident = get_client_ip(request) or self.get_ident(request)
        return self.cache_format % {"scope": self.scope, "ident": ident}


class TokenIssueThrottle(SimpleRateThrottle):
    """
    Limita los intentos de canjear una clave de API por un token.

    Se cuenta por IP y no por clave: contar por clave dejaria probar una clave
    distinta en cada intento sin gastar cuota.
    """

    scope = "auth"

    def get_cache_key(self, request, view):
        ident = get_client_ip(request) or self.get_ident(request)
        return self.cache_format % {"scope": self.scope, "ident": ident}
