"""user field matcher models"""
import re

from django.db import models
from django.utils.translation import gettext as _
from structlog import get_logger

from passbook.core.models import Policy
from passbook.policies.struct import PolicyRequest, PolicyResult

LOGGER = get_logger()


class PasswordPolicy(Policy):
    """Policy to make sure passwords have certain properties"""

    amount_uppercase = models.IntegerField(default=0)
    amount_lowercase = models.IntegerField(default=0)
    amount_symbols = models.IntegerField(default=0)
    length_min = models.IntegerField(default=0)
    symbol_charset = models.TextField(default=r"!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ ")
    error_message = models.TextField()

    form = 'passbook.policies.password.forms.PasswordPolicyForm'

    def passes(self, request: PolicyRequest) -> PolicyResult:
        # Only check if password is being set
        if not hasattr(request.user, '__password__'):
            return PolicyResult(True)
        password = getattr(request.user, '__password__')

        filter_regex = r''
        if self.amount_lowercase > 0:
            filter_regex += r'[a-z]{%d,}' % self.amount_lowercase
        if self.amount_uppercase > 0:
            filter_regex += r'[A-Z]{%d,}' % self.amount_uppercase
        if self.amount_symbols > 0:
            filter_regex += r'[%s]{%d,}' % (self.symbol_charset, self.amount_symbols)
        result = bool(re.compile(filter_regex).match(password))
        if not result:
            return PolicyResult(result, self.error_message)
        return PolicyResult(result)

    class Meta:

        verbose_name = _('Password Policy')
        verbose_name_plural = _('Password Policies')