from django.apps import apps
from django.contrib.auth.models import Permission, User
from django.db import models


def app_labels() -> set:
    """returns set of all current app labels"""
    return set(apps.app_configs.keys())


def users_with_permission(
    permission: Permission, include_superusers=True
) -> models.QuerySet:
    """returns queryset of users that have the given Django permission

    Args:
        permission: required permission
        include_superusers: whether superusers are included in the returned list
    """
    users_qs = (
        permission.user_set.all()
        | User.objects.filter(
            groups__in=list(permission.group_set.values_list("pk", flat=True))
        )
        | User.objects.select_related("profile").filter(
            profile__state__in=list(permission.state_set.values_list("pk", flat=True))
        )
    )
    if include_superusers:
        users_qs |= User.objects.filter(is_superuser=True)
    return users_qs.distinct()
