import asyncio
from uuid import UUID, uuid4

from maps_adv.points.server.lib.data_managers import ForecastsDataManager
from maps_adv.warden.client.lib.client import Client as WardenClient


class SyncForecasts:
    __slots__ = "id", "dm", "warden_client"

    id: UUID
    dm: ForecastsDataManager
    warden_client: WardenClient

    task_type = "points__sync_forecasts"
    relaunch_interval = 10

    def __init__(self, dm: ForecastsDataManager, warden_url: str):
        self.id = uuid4()
        self.dm = dm
        self.warden_client = WardenClient(
            server_url=warden_url, executor_id=str(self.id), task_type=self.task_type
        )

    @classmethod
    async def schedule(cls, dm: ForecastsDataManager, warden_url: str):
        while True:
            await asyncio.wait([cls(dm, warden_url)()])

    async def __call__(self):
        try:
            task = await self.warden_client.create_task()
        except Exception:
            await asyncio.sleep(self.relaunch_interval)
            return

        try:
            await asyncio.wait_for(self.dm.sync_forecasts(), timeout=task["time_limit"])
        except Exception:
            await self.warden_client.update_task(task["task_id"], "failed")
            raise
        else:
            return await self.warden_client.update_task(task["task_id"], "completed")
