from __future__ import annotations import logging from yuxi.channel.extensions.zalouser.errors import ( ZaloUserAuthError, ZaloUserConnectionError, ) from yuxi.channel.extensions.zalouser.sidecar_client import ZcaSidecarClient logger = logging.getLogger(__name__) class ZaloUserAuthAdapter: def __init__(self): self._client: ZcaSidecarClient | None = None def set_client(self, client: ZcaSidecarClient) -> None: self._client = client async def login_with_qr_start( self, account_id: str | None = None, *, force: bool = False, timeout_ms: int | None = None, ) -> dict: if not self._client: raise ZaloUserAuthError("Sidecar client not initialized") timeout = timeout_ms or 30_000 try: result = await self._client.login_qr_start(force=force, timeout_ms=timeout) return { "qr_data_url": result.get("qrDataUrl", ""), "message": result.get("message", "QR code generated"), "connected": result.get("connected", False), } except ZaloUserConnectionError as e: return {"qr_data_url": "", "message": str(e), "connected": False} async def login_with_qr_wait( self, account_id: str | None = None, *, timeout_ms: int | None = None, current_qr_data_url: str | None = None, ) -> dict: if not self._client: raise ZaloUserAuthError("Sidecar client not initialized") timeout = timeout_ms or 120_000 try: result = await self._client.login_qr_wait(timeout_ms=timeout) return { "connected": True, "message": "Login successful", "qr_data_url": None, "user_id": result.get("user_id", ""), "display_name": result.get("display_name", ""), } except ZaloUserAuthError as e: return {"connected": False, "message": str(e), "qr_data_url": None} async def login_with_qr_cancel(self, account_id: str | None = None) -> dict: if not self._client: raise ZaloUserAuthError("Sidecar client not initialized") try: await self._client.login_qr_cancel() return {"cancelled": True} except Exception as e: logger.warning("QR cancel failed: %s", e) return {"cancelled": False, "error": str(e)} async def logout_account(self, ctx: object) -> dict: if not self._client: return {"cleared": False, "logged_out": None} try: await self._client.logout() return {"cleared": True, "logged_out": True} except Exception as e: logger.warning("Logout failed: %s", e) return {"cleared": False, "logged_out": None} async def ensure_session(self, timeout_ms: int = 20_000) -> dict: if not self._client: raise ZaloUserAuthError("Sidecar client not initialized") try: return await self._client.ensure_session(timeout_ms=timeout_ms) except ZaloUserConnectionError as e: raise ZaloUserAuthError(f"Session ensure failed: {e}") from e async def get_cookie(self) -> dict: if not self._client: raise ZaloUserAuthError("Sidecar client not initialized") return await self._client.get_cookie()