import hashlib

from ninja.security import HttpBearer
from ninja.errors import HttpError

from epdb.models import APIToken


class BearerTokenAuth(HttpBearer):
    def authenticate(self, request, token):
        if token is None:
            return None

        hashed_token = hashlib.sha256(token.encode()).hexdigest()
        user = APIToken.authenticate(hashed_token, hashed=True)
        if not user:
            raise HttpError(401, "Invalid or expired token")

        request.user = user
        return user


class OptionalBearerTokenAuth:
    """Bearer auth that allows unauthenticated access.

    Validates the Bearer token if present (401 on invalid token),
    otherwise lets the request through for anonymous/session access.
    """

    def __init__(self):
        self._bearer = BearerTokenAuth()

    def __call__(self, request):
        return self._bearer(request) or request.user
