"""限流准入封装: 后端故障必须报错而非放行(降级方向铁律)。

非降级设计说明: 缓存/遥测挂 → 静默;限流挂 → 若放行,多 worker 会同时
失去闸门直接击穿网关,故一律 GovernanceBackendError 上抛。
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from polygateway.errors import GovernanceBackendError, SourceNotConfiguredError

if TYPE_CHECKING:
    from polygateway.ports import Permit, RateLimiter
    from polygateway.types import SourceConfig, SourceStats


class QuotaGate:
    """RetryMW 面向限流后端的唯一入口;包装一切后端异常。"""

    def __init__(self, limiter: RateLimiter, *, scope: str) -> None:
        self._limiter = limiter
        # 后端故障即 scope 级不可用,异常须携 scope 供调用方定位(issue #7 §3.3)
        self._scope = scope

    async def try_acquire(self, source: SourceConfig) -> Permit | None:
        try:
            return await self._limiter.try_acquire(source.name, source.effective_est_tokens())
        except (GovernanceBackendError, SourceNotConfiguredError):
            raise
        except Exception as exc:
            raise GovernanceBackendError(
                f"限流后端故障(try_acquire): {exc}", scope=self._scope
            ) from exc

    async def stats(self, source: SourceConfig) -> SourceStats:
        try:
            return await self._limiter.source_stats(source.name)
        except (GovernanceBackendError, SourceNotConfiguredError):
            raise
        except Exception as exc:
            raise GovernanceBackendError(
                f"限流后端故障(source_stats): {exc}", scope=self._scope
            ) from exc

    async def mark_progress(self) -> None:
        try:
            await self._limiter.mark_progress()
        except (GovernanceBackendError, SourceNotConfiguredError):
            raise
        except Exception as exc:
            raise GovernanceBackendError(
                f"限流后端故障(mark_progress): {exc}", scope=self._scope
            ) from exc

    async def progress_age_s(self) -> float:
        try:
            return await self._limiter.progress_age_s()
        except (GovernanceBackendError, SourceNotConfiguredError):
            raise
        except Exception as exc:
            raise GovernanceBackendError(
                f"限流后端故障(progress_age_s): {exc}", scope=self._scope
            ) from exc
