# -*- coding: utf-8 -*-
import re

from django.utils.timezone import get_current_timezone_name
from django.utils.translation import force_text

from .compat.dj import is_installed


def find_placeholder_relation(obj):
    return 'page'


class classproperty(object):
    """Like @property, but for classes, not just instances.

    Example usage:

        >>> from cms.utils.helpers import classproperty
        >>> class A(object):
        ...     @classproperty
        ...     def x(cls):
        ...         return 'x'
        ...     @property
        ...     def y(self):
        ...         return 'y'
        ...
        >>> A.x
        'x'
        >>> A().x
        'x'
        >>> A.y
        <property object at 0x2939628>
        >>> A().y
        'y'

    """
    def __init__(self, fget):
        self.fget = fget

    def __get__(self, owner_self, owner_cls):
        return self.fget(owner_cls)


def normalize_name(name):
    """
    Converts camel-case style names into underscore seperated words. Example::

        >>> normalize_name('oneTwoThree')
        'one_two_three'
        >>> normalize_name('FourFiveSix')
        'four_five_six'

    taken from django.contrib.formtools
    """
    new = re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', '_\\1', name)
    return new.lower().strip('_')


def get_header_name(name):
    """
    Returns "HTTP_HEADER_NAME" for "header-name" or "Header-Name", etc.
    Won't add "HTTP_" to input that already has it or for CONTENT_TYPE or
    CONTENT_LENGTH.
    """
    uc_name = re.sub(r'\W+', '_', force_text(name)).upper()
    if (uc_name in ['CONTENT_LENGTH', 'CONTENT_TYPE'] or
            uc_name.startswith('HTTP_')):
        return uc_name
    return 'HTTP_{0}'.format(uc_name)


def get_timezone_name():
    """
    This returns a cross-platform compatible timezone name suitable for
    embedding into cache-keys. Its inclusion into cache-keys enables, but does
    not guarantee by itself, that dates are display correctly for the client's
    timezone. In order to complete this the project should use middleware or
    some other mechanism to affect's Django's get_current_timezone_name().
    """
    # The datetime module doesn't restrict the output of tzname().
    # Windows is known to use non-standard, locale-dependant names.
    # User-defined tzinfo classes may return absolutely anything.
    # Hence this paranoid conversion to create a valid cache key.
    tz_name = force_text(get_current_timezone_name(), errors='ignore')
    return tz_name.encode('ascii', 'ignore').decode('ascii').replace(' ', '_')


def reversion_register(model_class, fields=None, follow=(), format="json", exclude_fields=None):
    """CMS interface to reversion api - helper function. Registers model for
    reversion only if reversion is available.

    Auto excludes publisher fields.
    """

    #FIXME: Remove this when integrating djangocms-reversion
    # reversion's merely recommended, not required
    if not is_installed('reversion'):
        return

    if fields and exclude_fields:
        raise ValueError("Just one of fields, exclude_fields arguments can be passed.")

    opts = model_class._meta
    local_fields = opts.local_fields + opts.local_many_to_many

    if fields is None:
        fields = [field.name for field in local_fields]

    exclude_fields = exclude_fields or []

    fields = filter(lambda name: not name in exclude_fields, fields)

    from cms.utils import reversion_hacks
    reversion_hacks.register_draft_only(model_class, fields, follow, format)
