from functools import wraps
import logging

from staff.achievery.exceptions import PermissionError

from .base import DomainObjectField


logger = logging.getLogger(__name__)


def check_perm(perm, exception):
    def decorator(method):

        @wraps(method)
        def wrapped(self, instance, *args, **kwargs):
            if instance.roles.check(self.name, perm):
                return method(self, instance, *args, **kwargs)
            else:
                raise exception(self.name, data=self.name)

        return wrapped
    return decorator


class PlainField(DomainObjectField):

    def __get__(self, instance, owner):
        return self.get(instance, owner)

    @check_perm('w', PermissionError)
    def __set__(self, instance, value):
        self.set(instance, value)

    def get(self, instance, owner):
        return getattr(instance.model, self.name)

    def set(self, instance, value):
        # logger.debug('Setting %r.%s = %r', instance.model, self.name, value)
        setattr(instance.model, self.name, value)
