from __future__ import annotations


class PermissionDenied(Exception):
    """Raised when a requested operation is not allowed for a registered model."""


PERMISSIONS = {"read", "create", "update", "delete"}


def validate_permissions(permissions: set[str] | list[str] | tuple[str, ...]) -> set[str]:
    """Validate and return a set of permission strings.

    Args:
        permissions: The requested permissions.

    Returns:
        The validated permission set.

    Raises:
        ValueError: If an unknown permission is provided.
    """
    perms = set(permissions)
    invalid = perms - PERMISSIONS
    if invalid:
        msg = f"Invalid permissions: {', '.join(sorted(invalid))}"
        raise ValueError(msg)
    return perms


def check_permission(allowed: set[str], action: str) -> None:
    """Check whether *action* is in *allowed*.

    Args:
        allowed: The set of allowed permissions for a model.
        action: The action being attempted (e.g. 'read', 'delete').

    Raises:
        PermissionDenied: If the action is not allowed.
    """
    if action not in allowed:
        msg = f"Permission '{action}' is not granted for this model."
        raise PermissionDenied(msg)
