from __future__ import annotations
from dataclasses import dataclass
from .db import TlsTestDB

HOURLY_LIMIT = 10
HOURLY_WINDOW = 60 * 60


@dataclass
class RateDecision:
    allowed: bool
    reason: str = ""
    retry_after: int = 0


def check(db: TlsTestDB, client_ip: str | None) -> RateDecision:
    if not client_ip:
        return RateDecision(allowed=True)
    if db.count_ip_active(client_ip) > 0:
        return RateDecision(
            allowed=False,
            reason="同一IPから実行中/待機中のテストが既にあります。完了してから再度お試しください。",
            retry_after=60,
        )
    recent = db.count_ip_in_window(client_ip, HOURLY_WINDOW)
    if recent >= HOURLY_LIMIT:
        return RateDecision(
            allowed=False,
            reason=f"1時間あたり{HOURLY_LIMIT}件の上限に達しました。時間をおいて再度お試しください。",
            retry_after=HOURLY_WINDOW,
        )
    return RateDecision(allowed=True)


def client_ip_from_scope(scope) -> str | None:
    headers = dict(scope.get("headers", []))
    xff = headers.get(b"x-forwarded-for", b"").decode(errors="ignore")
    if xff:
        return xff.split(",")[0].strip()
    client = scope.get("client")
    if client and len(client) >= 1:
        return str(client[0])
    return None
