__author__ = 'RemiZOffAlex'
__email__ = 'remizoffalex@mail.ru'

# import json
# from pathlib import Path

from flask import abort
from functools import wraps
from .. import app, lib, models


class ACL:
    """Декоратор для управления доступом
    """
    def __init__(self, view_func):
        # data = {}
        # acl_file = Path(app.config['DIR_DATA'] + "/acl.json")
        # if acl_file.exists():
        #     with open(acl_file, 'r') as fd:
        #         data = json.load(fd)
        # if view_func.__module__ not in data:
        #     data[view_func.__module__] = []
        # if view_func.__name__ not in data[view_func.__module__]:
        #     data[view_func.__module__].append(view_func.__name__)
        # with open(acl_file, 'w') as fd:
        #     json.dump(data, fd)
        funcname = view_func.__name__
        modulename = view_func.__module__
        resource = models.db_session.query(
            models.ACLResource
        ).filter(
            models.ACLResource.funcname == funcname,
            models.ACLResource.modulename == modulename
        ).first()
        if resource is None:
            resource = models.ACLResource(
                modulename=modulename,
                funcname=funcname
            )
            models.db_session.add(resource)
            models.db_session.commit()
        self.view_func = view_func
        wraps(view_func)(self)

    def __call__(self, *args, **kwargs):
        """Текущий объект, на который проверяем наличие прав
        """
        resource = models.db_session.query(
            models.ACLResource.id
        ).filter(
            models.ACLResource.funcname == self.view_func.__name__,
            models.ACLResource.modulename == self.view_func.__module__
        ).first()

        rule = models.db_session.query(
            models.ACLUserRule.permission
        ).filter(
            models.ACLUserRule.user_id == lib.get_user().id,
            models.ACLUserRule.resource_id == resource.id
        ).first()
        if rule is None:
            roles = models.db_session.query(
                models.ACLUserRole.role_id
            ).filter(
                models.ACLUserRole.user_id == lib.get_user().id
            )
            rolerule = models.db_session.query(
                models.ACLRoleRule
            ).filter(
                models.ACLRoleRule.role_id.in_(roles),
                models.ACLRoleRule.resource_id == resource.id
            ).first()
            if rolerule is None:
                if app.config['DEFAULT_PERMISSION'] == 'deny':
                    abort(403)
            elif rolerule.permission == 'deny':
                    abort(403)
        elif rule.permission == 'deny':
                abort(403)
        # maybe do something before the view_func call
        response = self.view_func(*args, **kwargs)
        # maybe do something after the view_func call
        return response
