"""CredsRefreshMiddleware — the passive half of the reload contract, on the request path.

WHY MIDDLEWARE AND NOT THE PERMISSION CLASS
-------------------------------------------
DRF resolves AUTHENTICATION before permissions (`APIView.initial()` calls `perform_authentication()`
first), and authentication reads `settings.ANDREA_SVC_KEYS`. Refreshing that setting from inside a
permission class would therefore be one request too late for the very request that presented the
NEW key. Middleware runs before the view is entered at all, so the refresh lands in time.

WHAT IT COSTS
-------------
One `ServiceSecrets.get()` per request, which is one `os.stat()` per DECLARED env file plus one on
the generation stamp — and for an unmigrated service (no declared files) it is a single stat. No
network: tier 1 is never fetched on the read path unless ANDREA_CREDS_TTL is explicitly set.

WHAT IT BUYS
------------
  * the bootstrap: a service with NO key cannot authenticate the endpoint that would give it one, so
    provisioning must not depend on that endpoint. A key dropped into a declared env file goes live
    here, on the next request (§4c).
  * multi-worker convergence: gunicorn runs 2..8 worker PROCESSES and a reload POST reaches exactly
    one of them. Every worker stats; every worker converges.

FAIL-SOFT: anything that goes wrong here is swallowed and logged at DEBUG. A credential refresh must
never be able to 500 a request that would otherwise have succeeded.
"""
import logging

from .creds import refresh_auth_settings

log = logging.getLogger("andrea_svc_web")


class CredsRefreshMiddleware:
    """Re-resolve the service key (mtime-gated) before the view runs."""

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        try:
            refresh_auth_settings()
        except Exception:                                    # noqa: BLE001 — never fail a request on this
            log.debug("creds: per-request auth refresh failed", exc_info=True)
        return self.get_response(request)
