"""Celery transport adapter for the Sandai operator client."""

import logging
from typing import Any, Dict, Optional

from celery import Celery
from celery.result import AsyncResult

from .config import ClientConfig


class CeleryTransport:
    """Wrap Celery app creation and task/result interactions."""

    def __init__(self, config: ClientConfig, logger: Optional[logging.Logger] = None):
        self.config = config
        self.logger = logger or logging.getLogger(__name__)
        self.app = self._create_celery_app()

    def _create_celery_app(self) -> Celery:
        app = Celery(self.config.app_name)
        app.conf.update(
            broker_url=self.config.broker_url,
            result_backend=self.config.result_backend,
            task_serializer=self.config.celery.task_serializer,
            result_serializer=self.config.celery.result_serializer,
            accept_content=self.config.celery.accept_content,
            broker_pool_limit=20,
            broker_connection_retry_on_startup=True,
            broker_connection_retry=True,
            result_backend_max_retries=3,
        )
        return app

    def send_task(self, task_name: str, *, kwargs: Dict[str, Any], queue: str) -> AsyncResult:
        if self.config.debug:
            self.logger.debug("sending task to queue=%s payload=%s", queue, kwargs)
        result = self.app.send_task(task_name, kwargs=kwargs, queue=queue)
        if self.config.debug:
            self.logger.debug("task submitted id=%s", getattr(result, "id", None))
        return result

    def get_result(self, async_result: AsyncResult, *, timeout: int) -> Any:
        result = async_result.get(timeout=timeout, propagate=False)
        if isinstance(result, BaseException):
            raise result
        return result

    def forget(self, async_result: AsyncResult) -> None:
        async_result.forget()
