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

from clarabot_nano_common.common.protocol.request import NanoRequestContext
from clarabot_nano_common.server.base.handler.filesystem.mixin import AbstractNanoDriveHandlerEvalMixin
from clarabot_nano_common.utility.algorithm import dict_nested_get
from clarabot_nano_common.utility.path.chroot import ChrootPath

from clarabot_nano.gateway.config import GatewayConfig
from clarabot_nano.gateway.handler.base import AbstractNanoGatewayHandler
from clarabot_nano.gateway.state.gateway import GatewayState


class AbstractFileSystemGatewayHandler(AbstractNanoGatewayHandler, AbstractNanoDriveHandlerEvalMixin):
    chroot: ChrootPath = None

    def __init__(self, helper: GatewayState, extracted_config: GatewayConfig, context: dict, payload: dict):
        AbstractNanoGatewayHandler.__init__(self, helper, extracted_config, context, payload)
        self.chroot = self.resolve_chroot(extracted_config)

    async def _create_request_key(self, secure: bool = False) -> Tuple[bool, Optional[list], int]:
        raise NotImplementedError()

    def _log_message(self) -> str:
        raise NotImplementedError()

    def build_error_message(self, buf: StringIO) -> None:
        raise NotImplementedError()

    def get_drive_root_for_error_message(self) -> Any:
        if self.chroot:
            return self.chroot.root
        try:
            return dict_nested_get(
                self.context,
                NanoRequestContext.ROOM,
                NanoRequestContext.ROOM_APIS,
                self.extracted_config.effective_drive_api,
                "path",
            )
        except KeyError:
            pass
