import logging
import asyncio

from pathlib import Path

from discord import File
from discord.ext import commands

from utils import permission_node
from .utils import isUp, sendCmd

log = logging.getLogger(f'charfred.{__name__}')


class TellmeHelper(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.loop = bot.loop
        self.servercfg = bot.servercfg

    def gettellmereport(self, server):
        """Retrieves the filename of the nth latest tellme file
        for a given server, in addition to the date of last modification.
        """

        tellmedir = Path(self.servercfg['serverspath'] + f'/{server}/config/tellme')
        _, rpath = max((r.stat().st_mtime, r) for r in tellmedir.iterdir())
        return rpath

    async def uploadreport(self, ctx, server):
        rpath = await self.loop.run_in_executor(None, self.gettellmereport, server)
        if not rpath:
            log.warning('Failed to find report file!')
            await ctx.sendmarkdown('< No report file found! >')
        else:
            log.info('Uploading TellMe report to Discord...')
            rfile = File(rpath)
            await ctx.send('```markdown\n# Here\'s the report! o7 :\n```', file=rfile)

    async def tellmecommand(self, ctx, server, ttype, tid=None):
        """Runs the tellme command via screen."""

        if server not in self.servercfg['servers']:
            await ctx.sendmarkdown(f'< I have no knowledge of {server}! >')
            return

        if not isUp(server):
            await ctx.sendmarkdown(f'< {server} is not up! >')
            return

        if tid:
            cmd = f'tellme locate {ttype} dump all-loaded-chunks {tid}'
        else:
            cmd = f'tellme loaded {ttype}' + (' dump' if ttype == 'chunks' else ' all dump')

        async with ctx.typing():
            log.info(f'Running tellme command: \"{cmd}\" on {server}.')
            await sendCmd(self.loop, server, cmd)
            await ctx.sendmarkdown(f'# Running TellMe command:\n  \"{cmd}\"')
            await asyncio.sleep(2, loop=self.loop)
            await self.uploadreport(ctx, server)

    @commands.group(invoke_without_command=False, aliases=['giveittomenow'])
    @permission_node(f'{__name__}.tellme')
    async def tellme(self, ctx):
        """Tellme plugin commands."""

        pass

    @tellme.command(aliases=['te'])
    @permission_node(f'{__name__}.tellme')
    async def tileentities(self, ctx, server: str):
        """Retrieves list of all loaded tileentities via TellMe."""

        await self.tellmecommand(ctx, server, 'tileentities-all')

    @tellme.command(aliases=['e'])
    @permission_node(f'{__name__}.tellme')
    async def entities(self, ctx, server: str):
        """Retrieves list of all loaded entities via TellMe."""

        await self.tellmecommand(ctx, server, 'entities-all')

    @tellme.command(aliases=['c'])
    @permission_node(f'{__name__}.tellme')
    async def chunks(self, ctx, server: str):
        """Retrieves list of all loaded chunks via TellMe."""

        await self.tellmecommand(ctx, server, 'chunks')

    @tellme.command()
    @permission_node(f'{__name__}.tellme')
    async def locate(self, ctx, server: str, targettype: str, targetid: str):
        """Finds specified block, tile entity, or entity via TellMe.

        Requires the type: block | te | entity
        and the ingame-id.
        """

        if targettype not in ('block', 'te', 'entity'):
            await ctx.sendmarkdown(f'< {targettype} is not a valid target type! >')
            return

        await self.tellmecommand(ctx, server, targettype, targetid)

    @tellme.command()
    @permission_node(f'{__name__}.tellme')
    async def download(self, ctx, server: str):
        """Downloads the latest TellMe report from given server."""

        await self.uploadreport(ctx, server)


def setup(bot):
    bot.register_nodes([f'{__name__}.tellme'])
    bot.add_cog(TellmeHelper(bot))

import logging
import asyncio

from pathlib import Path

from discord import File
from discord.ext import commands

from utils import permission_node
from .utils import isUp, sendCmd

log = logging.getLogger(f'charfred.{__name__}')


class TellmeHelper(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.loop = bot.loop
        self.servercfg = bot.servercfg

    def gettellmereport(self, server):
        """Retrieves the filename of the nth latest tellme file
        for a given server, in addition to the date of last modification.
        """

        tellmedir = Path(self.servercfg['serverspath'] + f'/{server}/config/tellme')
        _, rpath = max((r.stat().st_mtime, r) for r in tellmedir.iterdir())
        return rpath

    async def uploadreport(self, ctx, server):
        rpath = await self.loop.run_in_executor(None, self.gettellmereport, server)
        if not rpath:
            log.warning('Failed to find report file!')
            await ctx.sendmarkdown('< No report file found! >')
        else:
            log.info('Uploading TellMe report to Discord...')
            rfile = File(rpath)
            await ctx.send('```markdown\n# Here\'s the report! o7 :\n```', file=rfile)

    async def tellmecommand(self, ctx, server, ttype, tid=None):
        """Runs the tellme command via screen."""

        if server not in self.servercfg['servers']:
            await ctx.sendmarkdown(f'< I have no knowledge of {server}! >')
            return

        if not isUp(server):
            await ctx.sendmarkdown(f'< {server} is not up! >')
            return

        if tid:
            cmd = f'tellme locate {ttype} dump all-loaded-chunks {tid}'
        else:
            cmd = f'tellme loaded {ttype}' + (' dump' if ttype == 'chunks' else ' all dump')

        async with ctx.typing():
            log.info(f'Running tellme command: \"{cmd}\" on {server}.')
            await sendCmd(self.loop, server, cmd)
            await ctx.sendmarkdown(f'# Running TellMe command:\n  \"{cmd}\"')
            await asyncio.sleep(2, loop=self.loop)
            await self.uploadreport(ctx, server)

    @commands.group(invoke_without_command=False, aliases=['giveittomenow'])
    @permission_node(f'{__name__}.tellme')
    async def tellme(self, ctx):
        """Tellme plugin commands."""

        pass

    @tellme.command(aliases=['te'])
    @permission_node(f'{__name__}.tellme')
    async def tileentities(self, ctx, server: str):
        """Retrieves list of all loaded tileentities via TellMe."""

        await self.tellmecommand(ctx, server, 'tileentities-all')

    @tellme.command(aliases=['e'])
    @permission_node(f'{__name__}.tellme')
    async def entities(self, ctx, server: str):
        """Retrieves list of all loaded entities via TellMe."""

        await self.tellmecommand(ctx, server, 'entities-all')

    @tellme.command(aliases=['c'])
    @permission_node(f'{__name__}.tellme')
    async def chunks(self, ctx, server: str):
        """Retrieves list of all loaded chunks via TellMe."""

        await self.tellmecommand(ctx, server, 'chunks')

    @tellme.command()
    @permission_node(f'{__name__}.tellme')
    async def locate(self, ctx, server: str, targettype: str, targetid: str):
        """Finds specified block, tile entity, or entity via TellMe.

        Requires the type: block | te | entity
        and the ingame-id.
        """

        if targettype not in ('block', 'te', 'entity'):
            await ctx.sendmarkdown(f'< {targettype} is not a valid target type! >')
            return

        await self.tellmecommand(ctx, server, targettype, targetid)

    @tellme.command()
    @permission_node(f'{__name__}.tellme')
    async def download(self, ctx, server: str):
        """Downloads the latest TellMe report from given server."""

        await self.uploadreport(ctx, server)


def setup(bot):
    bot.register_nodes([f'{__name__}.tellme'])
    bot.add_cog(TellmeHelper(bot))

Retrieves the filename of the nth latest tellme file         for a given server, in addition to the date of last modification. # Here\'s the report! o7 :\n```', file=rfile) Runs the tellme command via screen. Tellme plugin commands. Retrieves list of all loaded tileentities via TellMe. Retrieves list of all loaded entities via TellMe. Retrieves list of all loaded chunks via TellMe. Finds specified block, tile entity, or entity via TellMe.          Requires the type: block | te | entity         and the ingame-id. Downloads the latest TellMe report from given server.