from django.conf import settings
from django.db.models.base import Model

from rest_framework.permissions import BasePermission, DjangoModelPermissions

VIEWSET_ACTION_MODEL_PERMISSION_MAP = {
    'list': '{app_label}.view_{model_name}',
    'retrieve': '{app_label}.view_{model_name}',
    'create': '{app_label}.add_{model_name}',
    'update': '{app_label}.change_{model_name}',
    'partial_update': '{app_label}.change_{model_name}',
    'destroy': '{app_label}.delete_{model_name}',
}

VIEWSET_ACTION_SUBMODEL_PERMISSION_MAP = {
    'list': '{app_label}.view_{model_name}',
    'retrieve': '{app_label}.view_{model_name}',
    'create': '{app_label}.change_{model_name}',
    'update': '{app_label}.change_{model_name}',
    'partial_update': '{app_label}.change_{model_name}',
    'destroy': '{app_label}.change_{model_name}',
}


def get_action_permission(action: str, model: Model, is_related: bool):
    permission_map = VIEWSET_ACTION_SUBMODEL_PERMISSION_MAP if is_related else VIEWSET_ACTION_MODEL_PERMISSION_MAP
    return permission_map[action].format(
        app_label=model._meta.app_label,
        model_name=model._meta.model_name,
    )


class IsSuperUser(BasePermission):
    """
    Доступ только для суперпользователя
    """
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_superuser)


class LabPermissions(DjangoModelPermissions):
    """
    Доступ к ручкам labapi при наличии соответствующих прав
    """
    CAN_VIEW = 'users.can_view_in_lab'
    CAN_EDIT = 'users.can_edit_in_lab'

    perms_map = {
        'GET': [CAN_VIEW],
        'OPTIONS': [],
        'HEAD': [],
        'POST': [CAN_EDIT],
        'PUT': [CAN_EDIT],
        'PATCH': [CAN_EDIT],
        'DELETE': [CAN_EDIT],
    }


class AllowedTVMServiceBasePermission(BasePermission):
    def has_permission(self, request, view):
        return False

    def has_object_permission(self, request, view, obj):
        tvm_service_id = getattr(request, 'tvm_service_id', None)
        if not tvm_service_id:
            return False
        # Для авторизации используется метод .has_permission
        return True


class EnvAllowedTVMServiceBasePermission(AllowedTVMServiceBasePermission):
    @property
    def allowed_tvm_ids(self):
        raise NotImplementedError

    def _has_permission(self, request):
        check_clients = getattr(settings, 'TVM_CHECK_CLIENTS', False)
        is_allowed_tvm = getattr(request, 'tvm_service_id', '') in self.allowed_tvm_ids
        return not check_clients or is_allowed_tvm

    def has_permission(self, request, view):
        return self._has_permission(request)

    def has_object_permission(self, request, view, obj):
        return self._has_permission(request)


class ApiAllowedTVMServicePermission(EnvAllowedTVMServiceBasePermission):
    @property
    def allowed_tvm_ids(self):
        return getattr(settings, 'TVM_API_ALLOWED_CLIENTS', [])


class LabApiAllowedTVMServicePermission(EnvAllowedTVMServiceBasePermission):
    @property
    def allowed_tvm_ids(self):
        return getattr(settings, 'TVM_LABAPI_ALLOWED_CLIENTS', [])
