import logging
from io import StringIO
from typing import Tuple, Optional

from clarabot_nano_common.common.handler.error import NanoHandlerError
from clarabot_nano_common.common.protocol.errors import NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST
from clarabot_nano_common.common.protocol.response import NanoBaseResponse
from clarabot_nano_common.server.base.handler.base import AbstractNanoServerHandler
from clarabot_nano_common.server.general.handler.base import AbstractGeneralNanoServerHandler

from clarabot_nano import __version__
from clarabot_nano.common.request.server_general import AdminGetInfoRequest


class AdminGetInfoResponse(NanoBaseResponse):
    NAME = "name"
    VERSION = "version"


class GetInfoHandler(AbstractGeneralNanoServerHandler):
    REQUIRES_OWNER_IDENTITY = True  # NOTE: No session to allow listing all Nanos with name easily.
    EXECUTION_STATE_CAN_CONFLICT = False  # cacheable and request_key are constant, no conflict is possible

    HANDLER_KEY = AdminGetInfoRequest.TYPE_KEY
    SUCCESS_LOG_LEVEL = logging.DEBUG  # do not log this normally

    async def _create_request_key(self, secure: bool = False) -> Tuple[bool, Optional[list], int]:
        return self._secure_request_key(False, None, 1) if secure else False, None, 1

    async def _execute_initial(self) -> dict:
        d = await AbstractNanoServerHandler._execute_initial(self)
        d[AdminGetInfoResponse.NAME] = self.extracted_config.name
        d[AdminGetInfoResponse.VERSION] = __version__
        return d

    async def _execute_part(self, part: int, s_hmac_start_part: Optional[int]) -> dict:  # pragma: no cover
        raise NanoHandlerError(NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST, "Part request is invalid", self)

    def _log_message(self) -> str:
        return "Query Nano info"

    def build_error_message(self, buf: StringIO) -> None:
        buf.write("Query Nano info")
