"""Tests for webhook routes — trigger, validation, rate limiting."""

import time

import pytest

from wled_controller.api.routes.webhooks import _check_rate_limit, _rate_hits


# ---------------------------------------------------------------------------
# Rate limiter unit tests (pure function, no HTTP)
# ---------------------------------------------------------------------------


class TestRateLimiter:
    def setup_method(self):
        """Clear rate-limit state between tests."""
        _rate_hits.clear()

    def test_allows_under_limit(self):
        for _ in range(29):
            _check_rate_limit("1.2.3.4")  # should not raise

    def test_rejects_at_limit(self):
        for _ in range(30):
            _check_rate_limit("1.2.3.4")
        from fastapi import HTTPException
        with pytest.raises(HTTPException) as exc_info:
            _check_rate_limit("1.2.3.4")
        assert exc_info.value.status_code == 429

    def test_separate_ips_independent(self):
        for _ in range(30):
            _check_rate_limit("10.0.0.1")
        # Different IP should still be allowed
        _check_rate_limit("10.0.0.2")  # should not raise

    def test_window_expiry(self):
        """Timestamps outside the 60s window are pruned."""
        old_time = time.time() - 120  # 2 minutes ago
        _rate_hits["1.2.3.4"] = [old_time] * 30
        # Old entries should be pruned, allowing new requests
        _check_rate_limit("1.2.3.4")  # should not raise


# ---------------------------------------------------------------------------
# Webhook payload validation
# ---------------------------------------------------------------------------


class TestWebhookPayload:
    def test_valid_payload_model(self):
        from wled_controller.api.routes.webhooks import WebhookPayload

        p = WebhookPayload(action="activate")
        assert p.action == "activate"

        p2 = WebhookPayload(action="deactivate")
        assert p2.action == "deactivate"

    def test_arbitrary_action_accepted_by_model(self):
        """The model accepts any string; validation is in the route handler."""
        from wled_controller.api.routes.webhooks import WebhookPayload

        p = WebhookPayload(action="bogus")
        assert p.action == "bogus"
