import datetime
import logging

from django.conf import settings


logger = logging.getLogger(__name__)


def oebs_str_to_datetime(val, default=None, raises=False):
    try:
        return datetime.datetime.strptime(val, settings.OEBS_DATETIME_FORMAT)
    except (ValueError, TypeError):
        logger.warning('OEBS returned date with strange format: {}'.format(val))
        if raises:
            raise
        return default


def oebs_str_to_date(val, default=None):
    try:
        return datetime.datetime.strptime(val, settings.OEBS_DATE_FORMAT).date()
    except (ValueError, TypeError):
        return default


def oebs_str_to_bool(val: str) -> bool:
    return val.lower() == settings.OEBS_TRUE_VALUE


def list_of(type_, convert_none=True, allow_excess_kw=True):
    def converter(list_of_dicts):
        if list_of_dicts is None:
            return [] if convert_none else None
        if allow_excess_kw:
            return [from_kwargs(type_, **kw) for kw in list_of_dicts]
        else:
            return [type_(**kw) for kw in list_of_dicts]

    return converter


def from_kwargs(type_, **kw):
    """ Create instance of attrs type_ ignoring excess keys in kw """
    actual_kw = {}
    for attr in type_.__attrs_attrs__:
        name = attr.name
        if name in kw:
            actual_kw[name] = kw[name]
    return type_(**actual_kw)


def ensure_cls(cls):
    """If the attribute is an instance of cls, pass, else try constructing."""
    def converter(val):
        if isinstance(val, cls):
            return val
        else:
            return cls(**val)
    return converter
