# Path: music/file_player.py
# class FilePlayer(AbstractMusicPlayer):
#     """
#     Audio player for playing local files.
#     """
#     __slots__ = ('default_path',)
# 
#     def __init__(self, logger, channel: VoiceChannel, default_path: Path):
#         """
#         :param logger: a logger object to do logging with.
#         :param channel: the `VoiceChannel` to play audio in.
#         :param default_path: the path to the playlist directory.
#         """
#         super().__init__(logger, channel)
#         self.default_path = default_path
# 
#     async def enqueue(self, ctx, query: str = None):
#         """
#         Bulk enqueue all files in the default play list directory into
#         `self.entry_queue`
# 
#         :param ctx: the `discord.Context` object.
# 
#         :param query: This isn't used.
#         """
#         if self.entry_queue:
#             return
#         files = [str(f) for f in self.default_path.iterdir()]
#         shuffle(files)
#         self.entry_queue.extend(Entry.from_file(ctx, file) for file in files)
# 
# Path: music/yt_player.py
# class YTPlayer(AbstractMusicPlayer):
#     """
#     Player to play audio from youtube-dl.
#     """
#     __slots__ = ()
# 
#     def __init__(self, logger, channel: VoiceChannel):
#         """
#         See `AbstractMusicPlayer.__init__`
#         """
#         super().__init__(logger, channel)
# 
#     async def enqueue(self, ctx: Context, query: str = None):
#         """
#         Search and enqueue one `Entry` from youtube-dl.
#         Does not enqueue if the search result is empty.
# 
#         :param ctx: the `discord.Context` object.
# 
#         :param query: the search query.
#         """
#         async with ctx.typing():
#             try:
#                 entry = await Entry.from_yt(ctx, query)
#             except DownloadError as e:
#                 self.logger.warn(str(e))
#                 await ctx.send('Sorry, this url is not supported.')
#                 return
#         if not entry:
#             await ctx.send(f'Search query {query} not found.')
#             return
#         self.entry_queue.append(entry)
#         await ctx.send(f'Enqueued:{entry.detail}')


from typing import Optional
from discord import VoiceChannel
from music.file_player import FilePlayer
from music.yt_player import YTPlayer



class GuildMusicManager:
    """
    Music player manager for a given guild.
    """
    __slots__ = ('player',)

    def __init__(self):
        self.player = None

    def __empty(self) -> bool:
        """
        :return: True if there's nothing playing and nothing in queue.
        """
        return not self.player or self.player.empty

    async def get_file_player(
            self, ctx, voice_channel: VoiceChannel) -> Optional[FilePlayer]:
        """
        Get a `FilePlayer`.
        If there's currently a non-empty `YTPlayer`, return None.

        :param ctx: the `discord.Context` object.

        :param voice_channel: the `VoiceChannel` to play audio in.

        :return: A `FilePlayer` instance if there's no non-empty `YTPlayer`.
        """

# Path: music/file_player.py
# class FilePlayer(AbstractMusicPlayer):
#     """
#     Audio player for playing local files.
#     """
#     __slots__ = ('default_path',)
# 
#     def __init__(self, logger, channel: VoiceChannel, default_path: Path):
#         """
#         :param logger: a logger object to do logging with.
#         :param channel: the `VoiceChannel` to play audio in.
#         :param default_path: the path to the playlist directory.
#         """
#         super().__init__(logger, channel)
#         self.default_path = default_path
# 
#     async def enqueue(self, ctx, query: str = None):
#         """
#         Bulk enqueue all files in the default play list directory into
#         `self.entry_queue`
# 
#         :param ctx: the `discord.Context` object.
# 
#         :param query: This isn't used.
#         """
#         if self.entry_queue:
#             return
#         files = [str(f) for f in self.default_path.iterdir()]
#         shuffle(files)
#         self.entry_queue.extend(Entry.from_file(ctx, file) for file in files)
# 
# Path: music/yt_player.py
# class YTPlayer(AbstractMusicPlayer):
#     """
#     Player to play audio from youtube-dl.
#     """
#     __slots__ = ()
# 
#     def __init__(self, logger, channel: VoiceChannel):
#         """
#         See `AbstractMusicPlayer.__init__`
#         """
#         super().__init__(logger, channel)
# 
#     async def enqueue(self, ctx: Context, query: str = None):
#         """
#         Search and enqueue one `Entry` from youtube-dl.
#         Does not enqueue if the search result is empty.
# 
#         :param ctx: the `discord.Context` object.
# 
#         :param query: the search query.
#         """
#         async with ctx.typing():
#             try:
#                 entry = await Entry.from_yt(ctx, query)
#             except DownloadError as e:
#                 self.logger.warn(str(e))
#                 await ctx.send('Sorry, this url is not supported.')
#                 return
#         if not entry:
#             await ctx.send(f'Search query {query} not found.')
#             return
#         self.entry_queue.append(entry)
#         await ctx.send(f'Enqueued:{entry.detail}')


# Path: music/guild_music_manager.py
from typing import Optional
from discord import VoiceChannel
from music.file_player import FilePlayer
from music.yt_player import YTPlayer




class GuildMusicManager:
    """
    Music player manager for a given guild.
    """
    __slots__ = ('player',)

    def __init__(self):
        self.player = None

    def __empty(self) -> bool:
        """
        :return: True if there's nothing playing and nothing in queue.
        """
        return not self.player or self.player.empty

    async def get_file_player(
            self, ctx, voice_channel: VoiceChannel) -> Optional[FilePlayer]:
        """
        Get a `FilePlayer`.
        If there's currently a non-empty `YTPlayer`, return None.

        :param ctx: the `discord.Context` object.

        :param voice_channel: the `VoiceChannel` to play audio in.

        :return: A `FilePlayer` instance if there's no non-empty `YTPlayer`.
        """

        if isinstance(self.player, YTPlayer) and not self.__empty():