from peewee import DoesNotExist
from .models import User
from .database import crypte
import logging
import bcrypt

logger = logging.getLogger('median')


class UserNotFound(Exception):
    def __init__(self, message):
        self.message = message


class UserPasswordFailed(Exception):
    def __init__(self, message):
        self.message = message


class BadgeNotFound(Exception):
    def __init__(self, message):
        self.message = message


def check_auth(user, passwd):
    """
    Check authentication

    return True if correct
    """
    try:
        User.get(username=user, password=crypte(passwd))
        logger.info('User "%s" found' % user)
    except DoesNotExist:
        logger.warning('User"%s" not found!' % user)
        return False

    return True


def check_badge(badge):
    """
    Check authentication with badge only

    return True if correct
    """
    try:
        User.get(badge=badge)
        logger.info('Badge "%s" found' % badge)
    except DoesNotExist:
        logger.warning('Badge "%s" not found!' % badge)
        return False

    return True


def user_auth(user, passwd):
    """
    Check the authentification for the user with:
    - Username
    - Login
    - Email

    :param user: Utilisateur de median
    :type  user: str
    :param passwd: Mot de passe de l'utilisateur
    :type  passwd: str
    :return: id of user, otherwise 0
    :rtype: int
    """
    try:
        usr = User.select().where(
            ((User.username == user) | (User.email == user) | (User.login == user))).get()

        if bcrypt.checkpw(passwd.encode('UTF_8'), usr.passwordWeb.encode('UTF_8')):
            logger.info('User "%s" found' % user)
        else:
            logger.warning('User "%s" wrong password!' % user)
            raise UserPasswordFailed("Password mismatch for user %s" % user)

    except DoesNotExist:
        logger.warning('User "%s" not found!' % user)
        raise UserNotFound("User %s not found!" % user)

    return usr.pk


def user_badge(badge):
    """
    Vérifie l'authentification de l'utilisateur par son badge

    :param badge: Code du badge utilisateur
    :type  badge: str
    :return: id of user, otherwise 0
    :rtype: int
    """
    try:
        usr = User.get(badge=badge)
        logger.info('Badge "%s" found' % badge)
    except DoesNotExist:
        logger.warning('Badge "%s" not found' % badge)
        raise BadgeNotFound("User for badge %s not found!" % badge)

    return usr.pk
