from __future__ import absolute_import
from __future__ import unicode_literals
from wiki.conf import settings

###############################
# ARTICLE PERMISSION HANDLING #
###############################
#
# All functions are:
#   can_something(article, user)
#      => True/False
#
# All functions can be replaced by pointing their relevant
# settings variable in wiki.conf.settings to a callable(article, user)


def can_read(article, user):
    if callable(settings.CAN_READ):
        return settings.CAN_READ(article, user)
    else:
        # Deny reading access to deleted articles if user has no delete access
        article_is_deleted = article.current_revision and article.current_revision.deleted
        if article_is_deleted and not article.can_delete(user):
            return False

        # Check access for other users...
        if user.is_anonymous() and not settings.ANONYMOUS:
            return False
        elif article.other_read:
            return True
        elif user.is_anonymous():
            return False
        if user == article.owner:
            return True
        if article.group_read:
            if article.group and user.groups.filter(
                    id=article.group.id).exists():
                return True
        if article.can_moderate(user):
            return True
        return False


def can_write(article, user):
    if callable(settings.CAN_WRITE):
        return settings.CAN_WRITE(article, user)
    # Check access for other users...
    if user.is_anonymous() and not settings.ANONYMOUS_WRITE:
        return False
    elif article.other_write:
        return True
    elif user.is_anonymous():
        return False
    if user == article.owner:
        return True
    if article.group_write:
        if article.group and user and user.groups.filter(
                id=article.group.id).exists():
            return True
    if article.can_moderate(user):
        return True
    return False


def can_assign(article, user):
    if callable(settings.CAN_ASSIGN):
        return settings.CAN_ASSIGN(article, user)
    return not user.is_anonymous() and user.has_perm('wiki.assign')


def can_assign_owner(article, user):
    if callable(settings.CAN_ASSIGN_OWNER):
        return settings.CAN_ASSIGN_OWNER(article, user)
    return False


def can_change_permissions(article, user):
    if callable(settings.CAN_CHANGE_PERMISSIONS):
        return settings.CAN_CHANGE_PERMISSIONS(article, user)
    return (
        not user.is_anonymous() and (
            article.owner == user or
            user.has_perm('wiki.assign')
        )
    )


def can_delete(article, user):
    if callable(settings.CAN_DELETE):
        return settings.CAN_DELETE(article, user)
    return not user.is_anonymous() and article.can_write(user)


def can_moderate(article, user):
    if callable(settings.CAN_MODERATE):
        return settings.CAN_MODERATE(article, user)
    return not user.is_anonymous() and user.has_perm('wiki.moderate')


def can_admin(article, user):
    if callable(settings.CAN_ADMIN):
        return settings.CAN_ADMIN(article, user)
    return not user.is_anonymous() and user.has_perm('wiki.admin')
