"""Tests for Generic Webhook adapter."""

import pytest

from wled_controller.core.game_integration.adapters.generic_webhook_adapter import (
    GenericWebhookAdapter,
)


class TestGenericWebhookParsing:
    def test_basic_mapping(self) -> None:
        config = {
            "adapter_id": "webhook_test",
            "mappings": [
                {
                    "source_path": "player.health",
                    "event": "health",
                    "min": 0,
                    "max": 100,
                    "trigger": "on_value",
                },
            ],
        }
        payload = {"player": {"health": 75}}
        events, _ = GenericWebhookAdapter.parse_payload(payload, config, {})
        assert len(events) == 1
        assert events[0].event_type == "health"
        assert events[0].value == pytest.approx(0.75)

    def test_multiple_mappings(self) -> None:
        config = {
            "adapter_id": "webhook_test",
            "mappings": [
                {
                    "source_path": "hp",
                    "event": "health",
                    "min": 0,
                    "max": 100,
                    "trigger": "on_value",
                },
                {"source_path": "mp", "event": "mana", "min": 0, "max": 200, "trigger": "on_value"},
            ],
        }
        payload = {"hp": 50, "mp": 100}
        events, _ = GenericWebhookAdapter.parse_payload(payload, config, {})
        assert len(events) == 2
        types = {e.event_type for e in events}
        assert types == {"health", "mana"}

    def test_empty_mappings(self) -> None:
        config = {"adapter_id": "test", "mappings": []}
        events, state = GenericWebhookAdapter.parse_payload({"hp": 50}, config, {})
        assert len(events) == 0

    def test_no_mappings_key(self) -> None:
        config = {"adapter_id": "test"}
        events, _ = GenericWebhookAdapter.parse_payload({"hp": 50}, config, {})
        assert len(events) == 0

    def test_diff_based_trigger(self) -> None:
        config = {
            "adapter_id": "test",
            "mappings": [
                {
                    "source_path": "kills",
                    "event": "kill",
                    "min": 0,
                    "max": 50,
                    "trigger": "on_increase",
                },
            ],
        }
        # First call — establish baseline
        _, state1 = GenericWebhookAdapter.parse_payload({"kills": 5}, config, {})

        # Increase — should emit
        events2, state2 = GenericWebhookAdapter.parse_payload({"kills": 6}, config, state1)
        assert len(events2) == 1
        assert events2[0].event_type == "kill"

        # Same — should not emit
        events3, _ = GenericWebhookAdapter.parse_payload({"kills": 6}, config, state2)
        assert len(events3) == 0

    def test_nested_json_path(self) -> None:
        config = {
            "adapter_id": "test",
            "mappings": [
                {
                    "source_path": "a.b.c",
                    "event": "health",
                    "min": 0,
                    "max": 10,
                    "trigger": "on_value",
                },
            ],
        }
        payload = {"a": {"b": {"c": 5}}}
        events, _ = GenericWebhookAdapter.parse_payload(payload, config, {})
        assert len(events) == 1
        assert events[0].value == pytest.approx(0.5)


class TestGenericWebhookAuth:
    def test_no_auth_configured(self) -> None:
        result = GenericWebhookAdapter.validate_auth({}, {}, {})
        assert result is True

    def test_bearer_auth_valid(self) -> None:
        result = GenericWebhookAdapter.validate_auth(
            {"Authorization": "Bearer secret123"},
            {},
            {"auth_token": "secret123"},
        )
        assert result is True

    def test_bearer_auth_invalid(self) -> None:
        result = GenericWebhookAdapter.validate_auth(
            {"Authorization": "Bearer wrong"},
            {},
            {"auth_token": "secret123"},
        )
        assert result is False

    def test_raw_token_auth(self) -> None:
        result = GenericWebhookAdapter.validate_auth(
            {"Authorization": "secret123"},
            {},
            {"auth_token": "secret123"},
        )
        assert result is True

    def test_custom_header(self) -> None:
        result = GenericWebhookAdapter.validate_auth(
            {"X-Custom": "mytoken"},
            {},
            {"auth_token": "mytoken", "auth_header": "X-Custom"},
        )
        assert result is True

    def test_missing_header(self) -> None:
        result = GenericWebhookAdapter.validate_auth(
            {},
            {},
            {"auth_token": "secret"},
        )
        assert result is False


class TestGenericWebhookMetadata:
    def test_adapter_type(self) -> None:
        assert GenericWebhookAdapter.ADAPTER_TYPE == "generic_webhook"

    def test_config_schema(self) -> None:
        schema = GenericWebhookAdapter.get_config_schema()
        assert "auth_token" in schema["properties"]
        assert "mappings" in schema["properties"]
        assert "auth_header" in schema["properties"]

    def test_setup_instructions(self) -> None:
        instructions = GenericWebhookAdapter.get_setup_instructions()
        assert "Webhook" in instructions
