from operator import itemgetter

from maps_adv.stat_controller.client.lib.collector import TaskStatus
from maps_adv.stat_tasks_starter.lib.base.pipeline import BasePipeline
from maps_adv.stat_tasks_starter.lib.config import config

from .collector import Collector


class Pipeline(BasePipeline):
    __slots__ = ("_collector",)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self._collector = self._setup_collector()

    def _setup_collector(self) -> Collector:
        settings = dict(
            host=config["CH_STORAGE_HOST"],
            port=config["CH_STORAGE_PORT"],
            user=config["CH_STORAGE_USER"],
            password=config["CH_STORAGE_PASSWORD"],
            database=config["CH_STORAGE_DB"],
            normalized_table=config["CH_STORAGE_NORMALIZED_TABLE"],
            accepted_groups_table=config["CH_STORAGE_ACCEPTED_GROUPS_TABLE"],
            accepted_table=config["CH_STORAGE_ACCEPTED_TABLE"],
            secure=config["CH_STORAGE_USE_SSL"],
            ca_certs=config["SSL_CERT_FILE"],
            lag=config["COLLECTOR_MATCHING_LAG"],
        )
        return Collector(**settings)

    async def __call__(self):
        task_data = await self._stat_client.find_new_task(executor_id=self.executor_id)
        task_id, timing_from, timing_to = itemgetter("id", "timing_from", "timing_to")(
            task_data
        )

        await self._collector(timing_from, timing_to)

        await self._update_task(task_id, TaskStatus.completed)

    async def _update_task(self, task_id: int, status: TaskStatus):
        await self._stat_client.update_task(
            task_id=task_id, status=status, executor_id=self.executor_id
        )
