"""HMAC-SHA256 webhook signature verification.

Pillar Cloud signs outbound tool-call POSTs with an ``X-Pillar-Signature``
header using the format ``t=<unix_ts>,v1=<hex_digest>``.  The signed payload
is ``b"{timestamp}.{raw_body}"``.

This module provides the customer-side verification function so the SDK can
reject forged or replayed requests.
"""
from __future__ import annotations

import hashlib
import hmac
import time


class SignatureVerificationError(Exception):
    """Raised when signature verification fails."""


def verify_webhook_signature(
    signature_header: str,
    body: bytes,
    secret: str,
    *,
    tolerance_seconds: int = 300,
) -> bool:
    """Verify an ``X-Pillar-Signature`` header value.

    Returns ``True`` when the HMAC matches and the timestamp is within
    *tolerance_seconds* of the current time.
    """
    if isinstance(body, str):
        body = body.encode()

    parts: dict[str, str] = {}
    for segment in signature_header.split(","):
        key, _, value = segment.partition("=")
        parts[key.strip()] = value.strip()

    ts = parts.get("t")
    sig = parts.get("v1")
    if not ts or not sig:
        return False

    try:
        ts_int = int(ts)
    except ValueError:
        return False

    if abs(time.time() - ts_int) > tolerance_seconds:
        return False

    signed_payload = f"{ts}.".encode() + body
    expected = hmac.new(
        secret.encode(),
        signed_payload,
        hashlib.sha256,
    ).hexdigest()

    return hmac.compare_digest(expected, sig)


def _generate_signature(body: bytes, secret: str, timestamp: int | None = None) -> str:
    """Generate a signature header value (for testing only)."""
    if isinstance(body, str):
        body = body.encode()

    ts = str(timestamp if timestamp is not None else int(time.time()))
    signed_payload = f"{ts}.".encode() + body
    digest = hmac.new(
        secret.encode(),
        signed_payload,
        hashlib.sha256,
    ).hexdigest()

    return f"t={ts},v1={digest}"
