from flask import abort, current_app
from flask_login import current_user
from flask_socketio import disconnect
from functools import wraps
from threading import Thread


def admin_required(f):
    @wraps(f)
    def wrapped(*args, **kwargs):
        if current_user.is_administrator:
            return f(*args, **kwargs)
        else:
            abort(403)
    return wrapped


def background(f):
    ''' This decorator executes a function in a Thread '''
    @wraps(f)
    def wrapped(*args, **kwargs):
        app = current_app._get_current_object()
        thread = Thread(target=f, args=(app, *args), kwargs=kwargs)
        thread.start()
        return thread
    return wrapped


def socketio_admin_required(f):
    @wraps(f)
    def wrapped(*args, **kwargs):
        if current_user.is_administrator:
            return f(*args, **kwargs)
        else:
            disconnect()
    return wrapped


def socketio_login_required(f):
    @wraps(f)
    def wrapped(*args, **kwargs):
        if not current_user.is_authenticated:
            disconnect()
        else:
            return f(*args, **kwargs)
    return wrapped