from aiohttp import web
from telebot.async_telebot import AsyncTeleBot

from smb.common.multiruntime.lib import is_arcadia_python
from maps_adv.common.lasagna import Lasagna
from maps_adv.geosmb.tuner.client import TunerClient
from maps_adv.geosmb.notification_bot.server.lib.bot.utils.error_handler import ExceptionHandler

from . import api
from .domain import Domain


class Application(Lasagna):
    SWIM_ENGINE_CLS = None

    async def _setup_layers(self, db: None) -> web.Application:
        clients = await self._setup_clients()

        self.domain = Domain(
            config=self.config,
            bot=clients["bot"],
            tuner_client=clients["tuner_client"],
        )

        _api = api.create(self.domain, webhook_path=self.config["WEBHOOK_URL_PATH"])
        _api.on_startup.append(lambda *a: self.domain.handle_startup())

        return _api

    async def _setup_clients(self) -> dict:
        return {
            "bot": AsyncTeleBot(
                token=self.config["BOT_TOKEN"],
                parse_mode="HTML",
                exception_handler=ExceptionHandler()
            ),
            "tuner_client": await TunerClient(
                url=self.config["TUNER_URL"],
                tvm=self.tvm,
                tvm_destination="tuner"
            ),
        }

    def run(self, *args, **kwargs) -> None:
        if not is_arcadia_python:
            raise RuntimeError("Server can work only in arcadia")
        return super().run(*args, **kwargs)
