import contextlib
import logging
from typing import Generator

from defence360agent.api.server import send_message, FGWSendMessgeException
from defence360agent.contracts.config import Core
from defence360agent.contracts.plugins import MessageSink
from defence360agent.internals.global_scope import g
from defence360agent.plugins.client import SendToServerClient
from defence360agent.utils import Scope

logger = logging.getLogger(__name__)


class SendToServerFGW(SendToServerClient, MessageSink):
    SCOPE = Scope.IM360

    @contextlib.contextmanager
    def _get_api(
        self,
    ) -> Generator[send_message.FileBasedGatewayAPI, None, None]:
        api = send_message.FileBasedGatewayAPI(Core.VERSION)

        yield self._set_api_attrs(api)

    async def _send_pending_messages(self) -> None:
        if self._pending.empty():
            return None

        messages = self._pending.pop_all()
        logger.info("Sending %s messages", len(messages))
        with self._get_api() as api:
            try:
                if g.get("DEBUG"):
                    logger.info(
                        "Writing messages to gw folder: %s",
                        list((m[0], m[1][:40], len(m[1])) for m in messages),
                    )
                await api.send_messages(messages)
                if self._pending.qsize() > 0:
                    logger.info(
                        "Still need to send %s messages",
                        self._pending.qsize(),
                    )
            except FGWSendMessgeException:
                self._pending.put_many(messages)

                logger.warning(
                    "Unsuccessful to send %s messages",
                    self._pending.qsize(),
                )
