import hashlib
import hmac
import time

import pytest

from gaiia import WebhookSignatureError, verify_webhook_signature


def _make_header(secret: str, timestamp: int, body: bytes) -> str:
    sig = hmac.new(
        secret.encode(), f"{timestamp}.{body.decode()}".encode(), hashlib.sha256
    ).hexdigest()
    return f"t={timestamp},v1={sig}"


def test_valid_signature_passes():
    secret = "whsec_test"
    body = b'{"hello":"world"}'
    ts = int(time.time())
    header = _make_header(secret, ts, body)
    verify_webhook_signature(header_value=header, raw_body=body, secret=secret)


def test_tampered_body_fails():
    secret = "whsec_test"
    body = b'{"hello":"world"}'
    ts = int(time.time())
    header = _make_header(secret, ts, body)
    with pytest.raises(WebhookSignatureError):
        verify_webhook_signature(
            header_value=header, raw_body=b'{"hello":"WORLD"}', secret=secret
        )


def test_old_timestamp_rejected():
    secret = "whsec_test"
    body = b'{"x":1}'
    ts = int(time.time()) - 3600
    header = _make_header(secret, ts, body)
    with pytest.raises(WebhookSignatureError):
        verify_webhook_signature(
            header_value=header, raw_body=body, secret=secret, tolerance_seconds=60
        )


def test_multiple_signatures_one_match():
    secret = "whsec_test"
    body = b"abc"
    ts = int(time.time())
    real = _make_header(secret, ts, body).split("v1=")[1]
    header = f"t={ts},v1=ffffffff,v1={real}"
    verify_webhook_signature(header_value=header, raw_body=body, secret=secret)


def test_missing_components():
    with pytest.raises(WebhookSignatureError):
        verify_webhook_signature(header_value="", raw_body=b"", secret="x")
    with pytest.raises(WebhookSignatureError):
        verify_webhook_signature(header_value="v1=abc", raw_body=b"", secret="x")
    with pytest.raises(WebhookSignatureError):
        verify_webhook_signature(header_value="t=123", raw_body=b"", secret="x")
