import uuid

from django.apps import apps
from django.conf import settings
from django.utils.text import slugify

from . import constants

DEFAULT_MODELS = {
    constants.RBAC_OU_MODEL_SETTING: 'django_rbac.OrganizationalUnit',
    constants.RBAC_ROLE_PARENTING_MODEL_SETTING: 'django_rbac.RoleParenting',
    constants.RBAC_ROLE_MODEL_SETTING: 'django_rbac.Role',
    constants.RBAC_PERMISSION_MODEL_SETTING: 'django_rbac.Permission',
}


def get_hex_uuid():
    return uuid.uuid4().hex


def get_swapped_model_name(setting):
    """Return a model qualified name given a setting name containing the
    qualified name of the model, useful to retrieve swappable models
    name.
    """
    if not hasattr(settings, setting):
        setattr(settings, setting, DEFAULT_MODELS[setting])
    return getattr(settings, setting)


def get_swapped_model(setting):
    """Return a model given a setting name containing the qualified name
    of the model, useful to retrieve swappable models.
    """
    app, model_name = get_swapped_model_name(setting).rsplit('.', 1)
    return apps.get_model(app, model_name)


def get_role_model_name():
    '''Returns the currently configured role model'''
    return get_swapped_model_name(constants.RBAC_ROLE_MODEL_SETTING)


def get_ou_model_name():
    '''Returns the currently configured organizational unit model'''
    return get_swapped_model_name(constants.RBAC_OU_MODEL_SETTING)


def get_role_parenting_model_name():
    '''Returns the currently configured role parenting model'''
    return get_swapped_model_name(constants.RBAC_ROLE_PARENTING_MODEL_SETTING)


def get_permission_model_name():
    '''Returns the currently configured permission model'''
    return get_swapped_model_name(constants.RBAC_PERMISSION_MODEL_SETTING)


def get_role_model():
    '''Returns the currently configured role model'''
    return get_swapped_model(constants.RBAC_ROLE_MODEL_SETTING)


def get_ou_model():
    '''Returns the currently configured organizational unit model'''
    return get_swapped_model(constants.RBAC_OU_MODEL_SETTING)


def get_role_parenting_model():
    '''Returns the currently configured role parenting model'''
    return get_swapped_model(constants.RBAC_ROLE_PARENTING_MODEL_SETTING)


def get_permission_model():
    '''Returns the currently configured permission model'''
    return get_swapped_model(constants.RBAC_PERMISSION_MODEL_SETTING)


def get_operation(operation_tpl):
    from . import models

    operation, created = models.Operation.objects.get_or_create(slug=operation_tpl.slug)
    return operation


def generate_slug(name, seen_slugs=None):
    slug = base_slug = slugify(name).lstrip('_')
    if seen_slugs:
        i = 1
        while slug in seen_slugs:
            slug = '%s-%s' % (base_slug, i)
    return slug
