from __future__ import annotations

import asyncio
from dataclasses import dataclass
from typing import Any, Callable


@dataclass(slots=True)
class ScheduledTimer:
    token: int = 0
    task: asyncio.Task | None = None


class TimerScheduler:
    def __init__(self, *, create_task_logged: Callable[..., asyncio.Task], logger: Any) -> None:
        self._create_task_logged = create_task_logged
        self._logger = logger
        self._timers: dict[str, ScheduledTimer] = {}

    def cancel(self, key: str, *, reason: str, log_name: str) -> None:
        timer = self._timers.get(key)
        if timer is None or timer.task is None:
            return
        if timer.task is asyncio.current_task():
            return
        if not timer.task.done():
            timer.task.cancel()
            self._logger.debug("%s | reason=%s", log_name, reason)
        timer.task = None

    def arm(
        self,
        key: str,
        *,
        task_name: str,
        coro,
    ) -> int:
        timer = self._timers.setdefault(key, ScheduledTimer())
        timer.token += 1
        token = timer.token
        timer.task = self._create_task_logged(coro, name=task_name)
        return token

    def is_current(self, key: str, token: int) -> bool:
        timer = self._timers.get(key)
        if timer is None:
            return False
        return timer.token == token
