# import the logging library
import logging
# Get an instance of a logger
logger = logging.getLogger(__name__)

import django.utils
from rest_framework import exceptions
from hawkrest import HawkAuthentication

from .models import Token
class APIHawk(HawkAuthentication):
    """This is the API authentication that is using the HAWK authentication mechanism.

    This class will implement a custom credentials and user lookups so that we can dynamically add new users and update tokens.
    """
    def hawk_credentials_lookup(self, id):
        """This method will perform the check if the used token is an existing/known token in the database. This will not lookup a user. Only an existing token.

        Args:
            id (string): The token key to lookup in the database for existing token.

        Raises:
            exceptions.AuthenticationFailed: If the given token does not exists.

        Returns:
            dict: The dictionary holds the token id, the token secret and the used hashing algoritem that is used.
        """
        try:
            token = Token.objects.get(key=id)
        except Token.DoesNotExist:
            logger.warning('Requested to validate with invalid/non existing token: {}'.format(id))
            raise exceptions.AuthenticationFailed('No such token: {}'.format(id))

        return {
            'id' : id,
            'key' : token.secret,
            'algorithm' : 'sha256'
        }

    def hawk_user_lookup(self, request, credentials):
        """Return the user account that is connected to the used token.

        Args:
            request ([type]): The incoming HTTP/API request
            credentials (dict): The credentials from ~hawk_credentials_lookup

        Raises:
            exceptions.AuthenticationFailed: If the given token does not exists to an existing user

        Returns:
            tuple: Returns a tuple holding the user as first item
        """
        user = None
        try:
            user = Token.objects.get(key=credentials['id']).user
        except Token.DoesNotExist:
            logger.warning('Requested to validate non existing user: {}'.format(id))
            raise exceptions.AuthenticationFailed('No user for token: {}'.format(credentials['id']))

        # Update the date time stamp to now for last access data
        user.token.last_access = django.utils.timezone.now()
        user.token.save()

        return (user,None)

    def __repr__(self):
        """Authentication identifier.

        Returns:
            string: Returns the name of the used authentication mechanism.
        """
        return 'Hawk authenticator'