from typing import Any, Awaitable, Callable, Dict, List

import aiohttp.web

from smb.common.multiruntime.lib.io import setup_filesystem
from smb.common.multiruntime.lib.revision import revision

from maps_adv.adv_store.client import Client as AdvStoreClient
from maps_adv.billing_proxy.client import Client as BillingProxyClient
from maps_adv.common.helpers.dsn_parser import parse
from maps_adv.common.lasagna import Lasagna
from maps_adv.warden.client.lib import TaskContext

from . import api, tasks

__all__ = ["Application"]

setup_filesystem("maps_adv/statistics/beekeeper/")


class Application(Lasagna):
    TASKS: Dict[str, Callable[[TaskContext, dict], Awaitable[None]]] = {
        "beekeeper__events_normalizer": tasks.events_normalizer,
        "beekeeper__events_normalizer_mapkit": tasks.events_normalizer_mapkit,
        "beekeeper__events_processor": tasks.events_processor,
        "beekeeper__paid_till_processor": tasks.paid_till_processor,
    }
    TASKS_KWARGS_KEYS: List[str] = [
        "config",
        "ch_config",
        "adv_store_client",
        "billing_proxy_client",
    ]

    build_revision: int
    config: dict
    ch_config: dict
    adv_store_client: AdvStoreClient
    billing_proxy_client: BillingProxyClient

    async def _setup_layers(self, db: Any) -> aiohttp.web.Application:
        api_ = api.create()

        self.ch_config = ch_config = parse(self.config["CH_STAT_DATABASE_URL"])
        ch_config.update(ch_config["hosts"][0])
        ch_config["alt_hosts"] = ",".join(
            "{}:{}".format(h["host"], h["port"]) for h in ch_config.pop("hosts")[1:]
        )
        ch_config["password"] = self.config["CH_STORAGE_PASSWORD"]
        ch_config["sync_request_timeout"] = self.config["CH_SYNC_REQUEST_TIMEOUT"]
        if ch_config["secure"] and not ch_config["ca_certs"]:
            ch_config["ca_certs"] = self.config["SSL_CERT_FILE"]

        self.build_revision = revision
        self.adv_store_client = AdvStoreClient(self.config["ADV_STORE_URL"])
        self.billing_proxy_client = BillingProxyClient(self.config["BILLING_URL"])

        return api_

    async def _setup_db(self) -> None:
        pass
