"""
Database models field validators.
"""

import os
import re

import pgpy

from django.apps import apps
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

from enterprise.constants import CONTENT_FILTER_FIELD_TYPES as cftypes


def get_app_config():
    """
    :return Application configuration.
    """
    return apps.get_app_config("enterprise")


def validate_hex_color(value):
    """
    Validate value is suitable for a color hex value.
    """
    pattern = r'^#[a-fA-F0-9]{6}$'
    if not re.match(pattern, value):
        message = _('Value entered is not a valid hex color code.')
        raise ValidationError(message)


def validate_image_extension(value):
    """
    Validate that a particular image extension.
    """
    config = get_app_config()
    ext = os.path.splitext(value.name)[1]
    if config and not ext.lower() in config.valid_image_extensions:
        raise ValidationError(_("Unsupported file extension."))


def validate_image_size(image):
    """
    Validate that a particular image size.
    """
    config = get_app_config()
    valid_max_image_size_in_bytes = config.valid_max_image_size * 1024
    if config and not image.size <= valid_max_image_size_in_bytes:
        raise ValidationError(
            _("The logo image file size must be less than or equal to %s KB.") % config.valid_max_image_size)


def validate_content_filter_fields(content_filter):
    """
    Validate particular fields (if present) passed in through content_filter are certain types.
    """
    for key, cftype in cftypes.items():
        if key in content_filter.keys():
            if not isinstance(content_filter[key], cftype['type']):
                raise ValidationError(
                    "Content filter '{}' must be of type {}".format(key, cftype['type'])
                )
            if cftype['type'] == list:
                if not all(cftype['subtype'] == type(x) for x in content_filter[key]):
                    raise ValidationError(
                        "Content filter '{}' must contain values of type {}".format(
                            key, cftype['subtype']
                        )
                    )


def validate_pgp_key(pgp_key):
    """
    Validate that given PGP key is valid.

    Raises:
        (ValidationError): Raised if given pgp_key is not valid.
    """
    try:
        pgpy.PGPKey.from_blob(pgp_key)
    except (ValueError, TypeError) as error:
        # Raise validation error in case of ValueError or TypeError.
        raise ValidationError('Invalid PGP Key provided.') from error
