'''
This plugin lets the user select and send a sticker from a pack of stickers.

The protocol used here is based on XEP-0363 and XEP-0066, while a future
version may use XEP-0449 instead.

Command
-------

.. glossary::
    /sticker
        **Usage:** ``/sticker <pack>``

        Opens a picker tool, and send the sticker which has been selected.

Configuration options
---------------------

.. glossary::
    sticker_picker
        **Default:** ``poezio-sticker-picker``

        The command to invoke as a sticker picker.  A sample one is provided in
        tools/sticker-picker.

    stickers_dir
        **Default:** ``XDG_DATA_HOME/poezio/stickers``

        The directory under which the sticker packs can be found.
'''

import asyncio
from poezio import xdg, tabs
from poezio.plugin import BasePlugin
from poezio.config import config
from poezio.core.structs import Completion
from poezio.windows.inputs import Input
from pathlib import Path
from asyncio.subprocess import PIPE


class Plugin(BasePlugin):
    dependencies = {'upload'}

    def init(self) -> None:
        # The command to use as a picker helper.
        self.picker_command = config.getstr('sticker_picker') or 'poezio-sticker-picker'

        # Select and create the stickers directory.
        directory = config.getstr('stickers_dir')
        if directory:
            self.directory = Path(directory).expanduser()
        else:
            self.directory = xdg.DATA_HOME / 'stickers'
        self.directory.mkdir(parents=True, exist_ok=True)

        self.upload = self.refs['upload']
        self.api.add_command(
            'sticker',
            self.command_sticker,
            usage='<sticker pack>',
            short='Send a sticker',
            help='Send a sticker, with a helper GUI sticker picker',
            completion=self.completion_sticker,
        )

    def command_sticker(self, pack: str) -> None:
        '''
        Sends a sticker
        '''
        if not pack:
            self.api.information('Missing sticker pack argument.', 'Error')
            return

        async def run_command(tab: tabs.ChatTab, path: Path) -> None:
            try:
                process = await asyncio.create_subprocess_exec(
                    self.picker_command, path, stdout=PIPE, stderr=PIPE)
                sticker, stderr = await process.communicate()
            except FileNotFoundError as err:
                self.api.information('Failed to launch the sticker picker: %s' % err, 'Error')
                return
            else:
                if process.returncode != 0:
                    self.api.information('Sticker picker failed: %s' % stderr.decode(), 'Error')
                    return
            if sticker:
                filename = sticker.decode().rstrip()
                self.api.information('Sending sticker %s' % filename, 'Info')
                await self.upload.send_upload(path / filename, tab)
        tab = self.api.current_tab()
        if not isinstance(tab, tabs.ChatTab):
            return
        path = self.directory / pack
        self.core.register_task(run_command(tab, path))

    def completion_sticker(self, the_input: Input) -> Completion:
        '''
        Completion for /sticker
        '''
        txt = the_input.get_text()[9:]
        directories = [directory.name for directory in self.directory.glob(txt + '*')]
        return Completion(the_input.auto_completion, directories, quotify=False)
