"""tests/test_monitoring_telemetry.py — Unit tests for TelemetryClient."""
import pytest
from unittest.mock import patch, MagicMock

pytestmark = pytest.mark.unit

FEATURES = [0.1, 0.5, 0.3, 0.2, 0.8, 0.1, 0.4, 0.6, 0.3, 0.7, 0.2]


class TestImport:
    def test_import_client(self):
        from llm_guard.monitoring.telemetry import TelemetryClient
        assert TelemetryClient is not None


class TestInstantiation:
    def test_enabled_with_token(self):
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="test-token", enabled=True)
        assert client._enabled is True

    def test_disabled_without_token(self):
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="", enabled=True)
        assert client._enabled is False  # no token → disabled

    def test_disabled_explicitly(self):
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="token", enabled=False)
        assert client._enabled is False

    def test_custom_repo(self):
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="t", repo="owner/repo")
        assert client._repo == "owner/repo"


class TestSubmit:
    def test_disabled_returns_false(self):
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="", enabled=False)
        result = client.submit(FEATURES, label=1)
        assert result is False

    def test_submit_returns_true_when_enabled(self):
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="test-token", enabled=True)
        # Patch the _send method to prevent actual network call
        with patch.object(client, "_send", return_value=None):
            result = client.submit(FEATURES, label=0, domain="test", version="0.55.0")
        # Should return True (thread launched)
        assert result is True

    def test_submit_no_error_on_network_fail(self):
        """Telemetry must never raise, even on network failure."""
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="test-token", enabled=True)
        with patch("urllib.request.urlopen", side_effect=Exception("network error")):
            result = client.submit(FEATURES, label=1)
        # Should not raise, just return bool
        assert isinstance(result, bool)

    def test_domain_hashed_in_payload(self):
        """Domain should be hashed before sending."""
        import hashlib
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="test-token", enabled=True)
        domain = "medical"
        expected_hash = hashlib.sha256(domain.encode()).hexdigest()[:6]
        captured = {}

        def fake_send(payload):
            captured.update(payload)

        with patch.object(client, "_send", side_effect=fake_send):
            client.submit(FEATURES, label=1, domain=domain, version="1.0")

        # Wait for thread (or may be immediate in test context)
        import time
        time.sleep(0.05)
        # Check captured payload if the thread ran in time
        if captured:
            assert captured.get("d") == expected_hash

    def test_payload_structure(self):
        from llm_guard.monitoring.telemetry import TelemetryClient
        client = TelemetryClient(github_token="token", enabled=True)
        captured = {}

        def fake_send(payload):
            captured.update(payload)

        with patch.object(client, "_send", side_effect=fake_send):
            client.submit(FEATURES, label=0, domain="test", version="0.55.0")

        import time
        time.sleep(0.05)
        if captured:
            assert "f" in captured
            assert "y" in captured
            assert captured["y"] == 0
            assert len(captured["f"]) == len(FEATURES)
