import functools

from im360.model.cache_sources import (
    CountryIPListCacheSource,
    GlobalwhitelistCacheSource,
    WhitelistCacheSourceFromCSF,
    WhitelistCacheSourceFromSystemSettings,
)
from im360.subsys import csf
from im360.utils.tree_cache import TreeCache
from im360.utils.tree_cache.adapters import TreeCacheCollector
from im360.model.firewall import IPList

cached = functools.lru_cache(maxsize=1)


class Services:
    """Class for definition and lazy initialization of used services."""

    @property
    @cached
    def primary_whitelist_cache(self):
        """:rtype: TreeCache"""
        db_cache = TreeCache(
            source=CountryIPListCacheSource(IPList.WHITE),
            full_sync_period=3600,
        )
        return TreeCacheCollector(db_cache, self.common_whitelist_cache)

    @property
    @cached
    def csf_whitelist_cache(self):
        """:rtype: TreeCache"""
        csf_files = csf.CSF_IMUNIFY_IPLISTS_MAPPING["WHITE"]
        csf_cache = TreeCache(source=WhitelistCacheSourceFromCSF(*csf_files))
        return TreeCacheCollector(
            csf_cache,
            self.common_whitelist_cache,
        )

    @property
    @cached
    def common_whitelist_cache(self):
        """:rtype: TreeCache"""
        return TreeCacheCollector(
            TreeCache(
                self.white_ips_source_from_system_settings, float("inf")
            ),
            self.global_whitelist_tree_cache,
        )

    @property
    @cached
    def white_ips_source_from_system_settings(self):
        return WhitelistCacheSourceFromSystemSettings()

    @property
    @cached
    def global_whitelist_cache_source(self):
        return GlobalwhitelistCacheSource()

    @property
    @cached
    def global_whitelist_tree_cache(self):
        """
        :return TreeCache: entity which is featured with .reset()
        """
        return TreeCache(self.global_whitelist_cache_source)


services = Services()
