## ircv3_2.py
# IRCv3.2 support (in progress).
from . import ircv3_1
from . import tags
from . import monitor
from . import metadata

__all__ = ["IRCv3_2Support"]


class IRCv3_2Support(
    metadata.MetadataSupport,
    monitor.MonitoringSupport,
    tags.TaggedMessageSupport,
    ircv3_1.IRCv3_1Support,
):
    """Support for some of IRCv3.2's extensions."""

    ## IRC callbacks.

    async def on_capability_account_tag_available(self, value):
        """Add an account message tag to user messages."""
        return True

    async def on_capability_cap_notify_available(self, value):
        """Take note of new or removed capabilities."""
        return True

    async def on_capability_chghost_available(self, value):
        """Server reply to indicate a user we are in a common channel with changed user and/or host."""
        return True

    async def on_capability_echo_message_available(self, value):
        """Echo PRIVMSG and NOTICEs back to client."""
        return True

    async def on_capability_invite_notify_available(self, value):
        """Broadcast invite messages to certain other clients."""
        return True

    async def on_capability_userhost_in_names_available(self, value):
        """Show full user!nick@host in NAMES list. We already parse it like that."""
        return True

    async def on_capability_uhnames_available(self, value):
        """Possibly outdated alias for userhost-in-names."""
        return await self.on_capability_userhost_in_names_available(value)

    async def on_isupport_uhnames(self, value):
        """Let the server know that we support UHNAMES using the old ISUPPORT method, for legacy support."""
        await self.rawmsg("PROTOCTL", "UHNAMES")

    ## API overrides.

    async def message(self, target, message):
        await super().message(target, message)
        if not self._capabilities.get("echo-message"):
            await self.on_message(target, self.nickname, message)
            if self.is_channel(target):
                await self.on_channel_message(target, self.nickname, message)
            else:
                await self.on_private_message(target, self.nickname, message)

    async def notice(self, target, message):
        await super().notice(target, message)
        if not self._capabilities.get("echo-message"):
            await self.on_notice(target, self.nickname, message)
            if self.is_channel(target):
                await self.on_channel_notice(target, self.nickname, message)
            else:
                await self.on_private_notice(target, self.nickname, message)

    ## Message handlers.

    async def on_raw(self, message):
        if "account" in message.tags:
            nick, _ = self._parse_user(message.source)
            if nick in self.users:
                metadata = {"identified": True, "account": message.tags["account"]}
                await self._sync_user(nick, metadata)
        await super().on_raw(message)

    async def on_raw_chghost(self, message):
        """Change user and/or host of user."""
        if "chghost" not in self._capabilities or not self._capabilities["chghost"]:
            return

        nick, _ = self._parse_user(message.source)
        if nick not in self.users:
            return

        # Update user and host.
        metadata = {"username": message.params[0], "hostname": message.params[1]}
        await self._sync_user(nick, metadata)
