"""Aria HMAC-Webhook Verification (KAR-232).

Helper functions fuer Webhook-Signaturen von GitHub, Linear, Telegram.
Nutzt hmac.compare_digest (timing-safe).

Verwendung in Webhook-Receivers (z.B. zukuenftige aria-api Routes):
    from aria_hmac import verify_github, verify_linear, verify_telegram

    @app.post("/webhook/github")
    async def github_webhook(req):
        body = await req.body()
        sig = req.headers.get("X-Hub-Signature-256", "")
        if not verify_github(body, sig, SECRET):
            return Response(status_code=401)
        # ... process
"""
from __future__ import annotations
import hmac
import hashlib
from typing import Callable


def _verify_hmac_sha256(body: bytes, signature_header: str, secret: str, prefix: str = "sha256=") -> bool:
    """Generic HMAC-SHA256 verify."""
    if not signature_header or not signature_header.startswith(prefix):
        return False
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    given = signature_header[len(prefix):]
    return hmac.compare_digest(expected, given)


def verify_github(body: bytes, signature_header: str, secret: str) -> bool:
    """GitHub: X-Hub-Signature-256: sha256=<hex>"""
    return _verify_hmac_sha256(body, signature_header, secret, prefix="sha256=")


def verify_linear(body: bytes, signature_header: str, secret: str) -> bool:
    """Linear: Linear-Signature: <hex> (no prefix)"""
    if not signature_header:
        return False
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)


def verify_telegram(body: bytes, secret_token: str, expected: str) -> bool:
    """Telegram: X-Telegram-Bot-Api-Secret-Token header — fixed-string compare."""
    return hmac.compare_digest(secret_token or "", expected or "")


def verify_stripe(body: bytes, signature_header: str, secret: str) -> bool:
    """Stripe: Stripe-Signature: t=<ts>,v1=<hex>"""
    if not signature_header:
        return False
    parts = dict(p.split("=", 1) for p in signature_header.split(",") if "=" in p)
    ts = parts.get("t", "")
    v1 = parts.get("v1", "")
    if not ts or not v1:
        return False
    payload = f"{ts}.{body.decode('utf-8', errors='replace')}".encode()
    expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, v1)
