import hashlib
import hmac
import time

from whatsrb_cloud.webhook_signature import WebhookSignature


class TestWebhookSignature:
    def _sign(self, payload: str, secret: str) -> str:
        digest = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
        return f"sha256={digest}"

    def test_valid_signature(self):
        payload = '{"event": "message.received"}'
        secret = "whsec_test123"
        signature = self._sign(payload, secret)

        assert WebhookSignature.verify(
            payload=payload, secret=secret, signature=signature
        ) is True

    def test_invalid_signature(self):
        payload = '{"event": "message.received"}'
        secret = "whsec_test123"

        assert WebhookSignature.verify(
            payload=payload, secret=secret, signature="sha256=invalid"
        ) is False

    def test_missing_prefix(self):
        payload = '{"event": "message.received"}'
        secret = "whsec_test123"

        assert WebhookSignature.verify(
            payload=payload, secret=secret, signature="noprefixhere"
        ) is False

    def test_empty_payload(self):
        assert WebhookSignature.verify(
            payload="", secret="secret", signature="sha256=abc"
        ) is False

    def test_empty_secret(self):
        assert WebhookSignature.verify(
            payload="data", secret="", signature="sha256=abc"
        ) is False

    def test_empty_signature(self):
        assert WebhookSignature.verify(
            payload="data", secret="secret", signature=""
        ) is False

    def test_valid_timestamp(self):
        payload = '{"event": "test"}'
        secret = "whsec_test"
        signature = self._sign(payload, secret)
        ts = str(int(time.time()))

        assert WebhookSignature.verify(
            payload=payload, secret=secret, signature=signature, timestamp=ts
        ) is True

    def test_stale_timestamp(self):
        payload = '{"event": "test"}'
        secret = "whsec_test"
        signature = self._sign(payload, secret)
        ts = str(int(time.time()) - 600)  # 10 minutes ago

        assert WebhookSignature.verify(
            payload=payload, secret=secret, signature=signature, timestamp=ts
        ) is False

    def test_custom_tolerance(self):
        payload = '{"event": "test"}'
        secret = "whsec_test"
        signature = self._sign(payload, secret)
        ts = str(int(time.time()) - 600)

        assert WebhookSignature.verify(
            payload=payload, secret=secret, signature=signature,
            timestamp=ts, tolerance=700
        ) is True

    def test_invalid_timestamp_format(self):
        payload = '{"event": "test"}'
        secret = "whsec_test"
        signature = self._sign(payload, secret)

        assert WebhookSignature.verify(
            payload=payload, secret=secret, signature=signature, timestamp="not_a_number"
        ) is False
