import logging

import safe_radix32

from clarabot_nano.core.config.update.base import AbstractRemoteConfigUpdateHandler

logger = logging.getLogger(__name__)


class CleanupDeadRoomsUpdateHandler(AbstractRemoteConfigUpdateHandler):
    HANDLER_KEY = "cleanup-dead-rooms"

    def __init__(self, default_config: dict, config: dict, local_config: dict):
        AbstractRemoteConfigUpdateHandler.__init__(self, default_config, config, local_config)
        self._dead_ids = set()

    def _execute(self, data: dict):
        if isinstance(dead_ids := data.get("dead_ids"), list):
            for dead_id in dead_ids:
                if isinstance(dead_id, int):
                    self._dead_ids.add(dead_id)
        if not self._dead_ids:
            raise Exception("Request has no valid dead room-ids to clean up")
        found_dead = False
        for d in self._c["drives"]:
            rooms = []
            for room in d.get("rooms", []):
                try:
                    if safe_radix32.decode(room) in self._dead_ids:
                        found_dead = True
                        continue
                except Exception:
                    pass  # NOTE: Do not remove invalid ids as a side-effect.
                rooms.append(room)
            d["rooms"] = rooms
        if not found_dead:
            raise Exception("No room found to be cleaned up by dead ids")

    def _describe_change(self, old_config: dict, new_config: dict, data: dict) -> str:
        dead_ids = []
        for dead_id in sorted(self._dead_ids):
            try:
                dead_ids.append(safe_radix32.encode_fw(dead_id))
            except Exception:  # pragma: no cover; no such int should be received...
                logger.error("Dead room-id out of range: %s", dead_id)
        return f"Cleaned up attachments to dead room-ids: {dead_ids!r}"
