import logging

from concurrent.futures import ProcessPoolExecutor

from saas.library.python.zk import ZKClient
from saas.tools.devops.fban.config import FBanConfig
from saas.tools.devops.fban.service import run_service_checks


class FBanChecker:
    def __init__(self, config: FBanConfig) -> None:
        self._config: FBanConfig = config

    def _do_run(self) -> None:
        with ProcessPoolExecutor(max_workers=len(self._config.services)) as pool:
            args = [(self._config, service) for service in self._config.services]
            for i, result in enumerate(pool.map(run_service_checks, args)):
                _, service = args[i]
                logging.warning('Finished the process for %s %s. Details:\n%s', service.service, service.ctype, result)

        logging.debug('Gracefully exiting fban...')

    async def run(self) -> None:
        logging.debug('Starting fban...')

        if self._config.dry_run:
            self._do_run()
            return

        zk_client = ZKClient()
        async with zk_client:
            lock = zk_client.create_write_lock(self._config.zk_lock_path)
            acquired = lock.acquire(blocking=True, ephemeral=True)

            if acquired:
                logging.debug('Start lock acquired...')
                self._do_run()
