from inspect import getargspec
from . import RpcException
from .dispatcher import register_method
from .sessions import get_session_by_token


class AccessDenied(RpcException):
    pass


def rpc_method(name, module=None):
    def _rpc_method(f):
        register_method(f, name, module)
        return f

    return _rpc_method


def check_permission(f_check):
    def wrapper(f):

        def _dec(*args, **kwargs):
            spec = getargspec(f)
            session = None
            if (len(args) - len(spec[0]) == 1 and not spec[3]) or spec[3]:
                session = get_session_by_token(args[0])
                if session:
                    kwargs['auth_token'] = args[0]
                    kwargs['request'].user = session['user']

            if (len(args) - len(spec[0]) == 1) or (session and session['token'] == args[0]):
                _args = tuple(list(args)[1:])
            else:
                _args = args

            if not f_check(*_args, **kwargs):
                raise AccessDenied('Access denied')

            if spec[2]:
                return f(*_args, **kwargs)
            else:
                return f(*_args)

        _dec.__name__ = f.__name__
        _dec.__module__ = f.__module__
        _dec.__doc__ = f.__doc__

        return _dec

    return wrapper


def _login_required(*args, **kwargs):
    if ('request' not in kwargs or not kwargs['request'].user or
            not kwargs['request'].user.is_authenticated()):
        return False
    return True


login_required = check_permission(_login_required)
