from __future__ import annotations

import asyncio
from time import monotonic

from .base import SubclientBase
from ..schemas import BackgroundTaskStatus


class BgTasksClient(SubclientBase):
    async def get_task_status(self, job_id: str) -> BackgroundTaskStatus:
        if not job_id:
            raise ValueError("job_id must be a non-empty string")

        response = await self._client.get(self._client.path(f"/bgtasks/{job_id}"))
        return self._client.parse(response, BackgroundTaskStatus)

    async def wait_for_task(
        self,
        job_id: str,
        timeout_seconds: float | None = 300.0,
        poll_interval_seconds: float = 1.0,
    ) -> BackgroundTaskStatus:
        if not job_id:
            raise ValueError("job_id must be a non-empty string")
        if timeout_seconds is not None and timeout_seconds < 0:
            raise ValueError("timeout_seconds must be non-negative or None")
        if poll_interval_seconds <= 0:
            raise ValueError("poll_interval_seconds must be greater than 0")

        start = monotonic()

        while True:
            status = await self.get_task_status(job_id)

            if status.ready:
                if status.failed or not status.success:
                    raise RuntimeError(f"Background task {job_id} failed")
                return status

            if timeout_seconds is not None and monotonic() - start >= timeout_seconds:
                raise TimeoutError(
                    f"Timed out while waiting for background task {job_id}"
                )

            await asyncio.sleep(poll_interval_seconds)
