import json
import logging
from datetime import timedelta

from maps_adv.common.config_loader import ConfigLoader, Option
from maps_adv.common.lasagna import setup_logging
from maps_adv.statistics.beekeeper.lib import Application


RECOGNISED_APP_TYPES = ["NAVIGATOR", "MOBILE_MAPS", "METRO", "BEEKEEPER"]


def _seconds(value: str) -> timedelta:
    return timedelta(seconds=int(value))


def _mapkit_source_app_filter(value: str) -> dict:
    data = json.loads(value)
    return {
        key: data[key]
        for key in (
            "ios_navi_build",
            "ios_maps_build",
            "ios_metro_build",
            "android_navi_build",
            "android_maps_build",
            "android_metro_build",
        )
    }


def _mapkit_recognised_apps(value: str) -> dict:
    source = json.loads(value)
    filtered = {k: v for k, v in source.items() if v in RECOGNISED_APP_TYPES}

    if len(filtered) != len(source):
        logging.warning("Not all recognised apps have proper types")
        logging.warning(f"   proper types: {RECOGNISED_APP_TYPES}")
        logging.warning(f"   recognised apps: {source}")
    return filtered


config = ConfigLoader(
    Option("CH_STAT_DATABASE_URL"),
    Option("CH_STORAGE_PASSWORD"),
    Option("CH_SYNC_REQUEST_TIMEOUT", default=60, converter=int),
    Option(
        "CH_MAX_MEMORY_USAGE",
        default=10 * 1024 * 1024 * 1024,
        converter=lambda data: int(data.strip()),
    ),
    Option("CH_NORMALIZER_QUERY_ID", default="maps_adv_beekeeper_normalizer_query"),
    Option("CH_PROCESSOR_QUERY_ID", default="maps_adv_beekeeper_processor_query"),
    Option("SSL_CERT_FILE", default=None),
    Option("ADV_STORE_URL"),
    Option("BILLING_URL"),
    Option("MIN_PACKET_SIZE", default=timedelta(seconds=300), converter=_seconds),
    Option("MAX_PACKET_SIZE", default=timedelta(seconds=600), converter=_seconds),
    Option("LAG_PACKET_SIZE", default=timedelta(seconds=10), converter=_seconds),
    Option("DEDUPLICATION_WINDOW", default=timedelta(seconds=240), converter=_seconds),
    Option("MAPKIT_SOURCE_APP_FILTER", default={}, converter=_mapkit_source_app_filter),
    Option("MAPKIT_NORMALIZER_TABLE_NAME", default="normalized_events_mapkit"),
    Option("MAPKIT_RECOGNISED_APPS", default={}, converter=_mapkit_recognised_apps),
    Option(
        "TIME_THRESHOLD_FREE_EVENTS",
        default=timedelta(seconds=14400),
        converter=_seconds,
    ),
    Option("WARDEN_URL", default="http://localhost:8080"),
    Option(
        "WARDEN_TASKS",
        default=[],
        converter=lambda data: [el.strip() for el in data.split(",") if el.strip()],
    ),
    # TODO(megadiablo) Костыль для проверки запуска кампаний в новой
    #                  статистике GEOPROD-3872, GEOPROD-4108. По этому
    #                  их только и необходимо обрабатывать.
    Option(
        "MONKEY_PATCH_CAMPAIGNS_FOR_BEEKEEPER",
        # None -- воспринимается как не необходимость все кампании
        # обрабатывать
        default=None,
        converter=lambda data: [
            int(item.strip()) for item in data.split(",") if item.strip()
        ],
    ),
    Option("EXPERIMENTAL_CHARGE_FIX_CAMPAIGNS", default=False, converter=bool),
)


def main():
    setup_logging()
    config.init()

    Application(config).run()


if __name__ == "__main__":
    main()
