from __future__ import annotations import time from typing import Any from yuxi.channels.models import HealthStatus from .helix import HelixClient async def health_check(config: dict[str, Any], timeout_ms: int = 10000) -> HealthStatus: start = time.monotonic() issues: list[str] = [] token = config.get("access_token", "") client_id = config.get("client_id", "") if not token or not client_id: return HealthStatus( status="unhealthy", last_error="Missing client_id or access_token", latency_ms=(time.monotonic() - start) * 1000, ) helix = HelixClient(client_id, token) try: await helix.start() user_info = await helix.validate_token() if user_info is None: issues.append("Token invalid or expired (401)") except Exception as e: issues.append(f"Helix API unreachable: {e}") finally: await helix.close() latency_ms = (time.monotonic() - start) * 1000 probe_timeout_ms = config.get("probe_timeout_ms", timeout_ms) if latency_ms > probe_timeout_ms: issues.append(f"Probe timeout: {latency_ms:.0f}ms > {probe_timeout_ms}ms") if issues: return HealthStatus( status="unhealthy", last_error="; ".join(issues), latency_ms=latency_ms, metadata={"timeout_ms": probe_timeout_ms}, ) return HealthStatus( status="healthy", latency_ms=latency_ms, metadata={"api": "helix", "timeout_ms": probe_timeout_ms}, ) async def validate_token(client_id: str, access_token: str) -> dict[str, Any] | None: helix = HelixClient(client_id, access_token) try: await helix.start() return await helix.validate_token() finally: await helix.close() async def get_broadcaster_id(client_id: str, access_token: str, channel_name: str) -> str | None: helix = HelixClient(client_id, access_token) try: await helix.start() user = await helix.get_user_by_name(channel_name) return user["id"] if user else None finally: await helix.close() async def refresh_access_token(client_id: str, client_secret: str, refresh_token: str) -> dict[str, Any] | None: helix = HelixClient(client_id, "") try: await helix.start() return await helix.refresh_user_token(client_secret, refresh_token) finally: await helix.close() async def get_app_access_token(client_id: str, client_secret: str) -> str | None: helix = HelixClient(client_id, "") try: await helix.start() return await helix.get_app_access_token(client_secret) finally: await helix.close()