from __future__ import annotations
from typing import TYPE_CHECKING

from discord.ext import commands

if TYPE_CHECKING:
    from .context import GuildContext

# The permission system of the bot is based on a "just works" basis
# You have permissions and the bot has permissions. If you meet the permissions
# required to execute the command (and the bot does as well) then it goes through
# and you can execute the command.
# Certain permissions signify if the person is a moderator or an
# admin (Administrator). Having these signify certain bypasses.
# Of course, the owner will always be able to execute commands.


async def check_permissions(ctx: GuildContext, perms: dict[str, bool], *, check=all):
    is_owner = await ctx.bot.is_owner(ctx.author)
    if is_owner:
        return True

    resolved = ctx.channel.permissions_for(ctx.author)
    return check(getattr(resolved, name, None) == value for name, value in perms.items())


def has_permissions(*, check=all, **perms: bool):
    async def pred(ctx: GuildContext):
        return await check_permissions(ctx, perms, check=check)

    return commands.check(pred)


async def check_guild_permissions(ctx: GuildContext, perms: dict[str, bool], *, check=all):
    is_owner = await ctx.bot.is_owner(ctx.author)
    if is_owner:
        return True

    if ctx.guild is None:
        return False

    resolved = ctx.author.guild_permissions
    return check(getattr(resolved, name, None) == value for name, value in perms.items())


def has_guild_permissions(*, check=all, **perms: bool):
    async def pred(ctx: GuildContext):
        return await check_guild_permissions(ctx, perms, check=check)

    return commands.check(pred)


# These do not take channel overrides into account


def is_manager():
    async def pred(ctx: GuildContext) -> bool:
        return await check_guild_permissions(ctx, {'manage_guild': True})

    return commands.check(pred)


def is_mod():
    async def pred(ctx: GuildContext) -> bool:
        return await check_guild_permissions(ctx, {'ban_members': True, 'manage_messages': True})

    return commands.check(pred)


def is_admin():
    async def pred(ctx: GuildContext) -> bool:
        return await check_guild_permissions(ctx, {'administrator': True})

    return commands.check(pred)


def admin_or_permissions(**perms: bool):
    perms['administrator'] = True

    async def predicate(ctx: GuildContext) -> bool:
        return await check_guild_permissions(ctx, perms, check=any)

    return commands.check(predicate)


def is_in_guilds(*guild_ids: int):
    def predicate(ctx: GuildContext) -> bool:
        guild = ctx.guild
        if guild is None:
            return False
        return guild.id in guild_ids

    return commands.check(predicate)


def is_lounge_cpp():
    return is_in_guilds(145079846832308224)

@@ -60,16 +60,68 @@
 CHECKING
+, Callable, TypeVar%0Afrom discord import app_commands
 %0A%0Afrom d
@@ -205,16 +205,34 @@
 ontext%0A%0A
+T = TypeVar('T')%0A%0A
 # The pe
@@ -1817,20 +1817,67 @@
 def 
-is_manager()
+hybrid_permissions_check(**perms: bool) -%3E Callable%5B%5BT%5D, T%5D
 :%0A  
@@ -1907,32 +1907,24 @@
 uildContext)
- -%3E bool
 :%0A        re
@@ -1925,707 +1925,605 @@
     
-return await check_guild_permissions(ctx, %7B'manage_guild': True%7D)%0A%0A    return commands.check(pred)%0A%0A%0Adef is_mod():%0A    async def pred(ctx: GuildContext) -%3E bool:%0A        return await check_guild_permissions(ctx, %7B'ban_members': True, 'manage_messages': True%7D)%0A%0A    return commands.check(pred)%0A%0A%0Adef is_admin():%0A    async def pred(ctx: GuildContext) -%3E bool:%0A        return await check_guild_permissions(ctx, %7B'administrator': True%7D)%0A%0A    return commands.check(pred)%0A%0A%0Adef admin_or_permissions(**perms: bool):%0A    perms%5B'administrator'%5D = 
+if ctx.interaction is not None:%0A            # For application commands just trust the admin set it up properly%0A            return True%0A        return await check_guild_permissions(ctx, perms)%0A%0A    def decorator(func: T) -%3E T:%0A        commands.check(pred)(func)%0A        app_commands.default_permissions(**perms)(func)%0A        return func%0A%0A    return decorator%0A%0A%0Adef is_manager():%0A    return hybrid_permissions_check(manage_guild=True)%0A%0A%0Adef is_mod():%0A    return hybrid_permissions_check(ban_members=True, manage_messages=
 True
+)
 %0A%0A
-    async def predicate(ctx: GuildContext) -%3E bool:%0A        return await check_guild_permissions(ctx, perms, check=any)%0A%0A    return commands.check(predicat
+%0Adef is_admin():%0A    return hybrid_permissions_check(administrator=Tru
 e)%0A%0A

Change permission checks to respect app command permissions