from rest_framework import permissions


class DjangoModelPermissionsWithView(permissions.DjangoModelPermissions):
    perms_map = {
        "GET": ["%(app_label)s.view_%(model_name)s"],
        "OPTIONS": [],
        "HEAD": [],
        "POST": ["%(app_label)s.add_%(model_name)s"],
        "PUT": ["%(app_label)s.change_%(model_name)s"],
        "PATCH": ["%(app_label)s.change_%(model_name)s"],
        "DELETE": ["%(app_label)s.delete_%(model_name)s"],
    }


def get_permission(model_t, perm_t: str) -> str:
    return f"{model_t._meta.app_label}.{perm_t}_{model_t._meta.model_name}"


class CreatorFullOrDjangoModelPermissions(permissions.DjangoModelPermissions):

    def has_permission(self, request, view):

        if not request.user or not request.user.is_authenticated:
            # Let the super class handle the resulting error message
            return super().has_permission(request, view)

        # Fall through to allow edit and delete permission
        # checks to happen at object level
        if request.method in ["PUT", "PATCH", "DELETE"]:
            return True

        return super().has_permission(request, view)

    def has_object_permission(self, request, view, obj):

        # Allow metadata checks on endpoint
        if request.method in ["HEAD", "OPTIONS"]:
            return True

        if not request.user or not request.user.is_authenticated:
            # Let the super class handle the resulting error message
            return super().has_permission(request, view)

        # Full permissions are only given to the creator of the object.
        if obj.creator.id == request.user.id:
            return True

        # Fall back to Django model permissions for everyone else
        return super().has_permission(request, view)
