import logging
from typing import Tuple, Optional

from clarabot_nano.common.handler.base import NanoHandlerError
from clarabot_nano.common.protocol.errors import (
    NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST,
    NANO_REQUEST_ERROR_HANDLER_DENIED,
)
from clarabot_nano.common.protocol.request import NanoRequestContext
from clarabot_nano.common.protocol.response import NanoBaseResponse
from clarabot_nano.common.request.gateway import NanoMutationIdCreateRequest
from clarabot_nano.gateway.config import GatewayConfig
from clarabot_nano.gateway.handler.base import AbstractNanoGatewayHandler
from clarabot_nano.gateway.state.gateway import GatewayState


class CreateMutationIdResponse(NanoBaseResponse):
    TOKEN = "token"


class CreateMutationIdHandler(AbstractNanoGatewayHandler):
    HANDLER_KEY = NanoMutationIdCreateRequest.TYPE_KEY
    SUCCESS_LOG_LEVEL = logging.DEBUG  # do not log this normally

    def __init__(self, helper: GatewayState, extracted_config: GatewayConfig, context: dict, payload: dict):
        AbstractNanoGatewayHandler.__init__(self, helper, extracted_config, context, payload)
        if self.context[NanoRequestContext.ACCOUNT_ID] == 0:
            raise NanoHandlerError(
                NANO_REQUEST_ERROR_HANDLER_DENIED, "Anonymous cannot create mutation-id token", self.context
            )
        self.token: str = None

    async def _create_request_key(self) -> Tuple[bool, Optional[list], int]:
        return False, None, 1

    async def _execute_initial(self) -> dict:
        d = await AbstractNanoGatewayHandler._execute_initial(self)
        d[CreateMutationIdResponse.TOKEN] = self.token = self.helper.mutate_tracker.create(
            self.context[NanoRequestContext.ACCOUNT_ID]
        )
        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.context)

    def _log_message(self) -> str:
        return f"Create new mutation-id: {self.token}"
