from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
from django.contrib.auth.models import User, AnonymousUser
from channels.db import database_sync_to_async

def get_user_from_token(token, log=False):
    if log:
        print("verifying token:", token)
    backend = OIDCAuthenticationBackend()
    try:
        claims = backend.verify_token(token)
    except Exception as e:
        raise AuthenticationFailed(f'Invalid token: {e}')
    return backend.filter_users_by_claims(claims).first()


class OIDCBearerTokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        auth = request.META.get('HTTP_AUTHORIZATION', '')
        if not auth.startswith('Bearer '):
            return None
        token = auth.split(' ')[1]
        user = get_user_from_token(token)
        if not user:
            raise AuthenticationFailed(f'Unknown user: {token}')
        return (user, None)

# @database_sync_to_async
# def get_user(user_id):
#     try:
#         return User.objects.get(id=user_id)
#     except User.DoesNotExist:
#         return AnonymousUser()

class QueryAuthMiddleware:
    """
    Custom middleware that takes user from passed token.
    """
    def __init__(self, app):
        # Store the ASGI application we were passed
        self.app = app

    async def __call__(self, scope, receive, send):
        scope['user'] = AnonymousUser()
        # print("Authing", scope)
        # data = await receive()
        # print("data: ", data)
        # token = data.get('token')
        # if token:
        #     user = database_sync_to_async(get_user_from_token(token, print=True))
        #     print("USER?", user)
        #     if user:
        #         scope['user'] = user
        #     else:
        #         pass

        return await self.app(scope, receive, send)
