"""Tests for AgentDrop.listen_sse() method."""

import threading
import time
from unittest.mock import patch, MagicMock

import pytest

from agentdrop.client import AgentDrop


@pytest.fixture
def client():
    """Create a client with known credentials."""
    return AgentDrop(
        api_key="agd_test_key_123",
        agent_id="test-agent",
        api_base="https://api.agent-drop.com",
    )


class TestListenSseAttributes:
    """Verify listen_sse uses the correct instance attributes (no AttributeError)."""

    def test_constructs_correct_url_and_headers(self, client):
        """listen_sse must use self.api_base, self.agent_id, self.api_key."""
        captured = {}

        def fake_get(url, headers=None, stream=False, timeout=None):
            captured["url"] = url
            captured["headers"] = headers
            # Return a response that will iterate zero lines then close
            resp = MagicMock()
            resp.raise_for_status = MagicMock()
            resp.iter_lines = MagicMock(return_value=iter([]))
            return resp

        with patch("agentdrop.client.requests.get", side_effect=fake_get):
            client.listen_sse(on_transfer=lambda d: None)
            # Give the thread a moment to make the request
            time.sleep(0.3)
            client.stop()

        assert "url" in captured, "requests.get was never called - listen_sse likely raised an AttributeError"
        assert captured["url"] == "https://api.agent-drop.com/v1/events/stream?agent_id=test-agent"
        assert captured["headers"]["Authorization"] == "Bearer agd_test_key_123"
        assert captured["headers"]["Accept"] == "text/event-stream"

    def test_url_without_agent_id(self):
        """When agent_id is None, the URL should not have a query param."""
        client_no_id = AgentDrop(api_key="agd_key", agent_id=None, config_dir="/nonexistent")
        # Force agent_id to None (constructor may load from local config)
        client_no_id.agent_id = None
        captured = {}

        def fake_get(url, headers=None, stream=False, timeout=None):
            captured["url"] = url
            resp = MagicMock()
            resp.raise_for_status = MagicMock()
            resp.iter_lines = MagicMock(return_value=iter([]))
            return resp

        with patch("agentdrop.client.requests.get", side_effect=fake_get):
            client_no_id.listen_sse(on_transfer=lambda d: None)
            time.sleep(0.3)
            client_no_id.stop()

        assert "url" in captured
        assert captured["url"] == "https://api.agent-drop.com/v1/events/stream"
        assert "agent_id" not in captured["url"]

    def test_listen_sse_starts_thread(self, client):
        """listen_sse should start a daemon listener thread."""
        with patch("agentdrop.client.requests.get") as mock_get:
            resp = MagicMock()
            resp.raise_for_status = MagicMock()
            resp.iter_lines = MagicMock(return_value=iter([]))
            mock_get.return_value = resp

            client.listen_sse(on_transfer=lambda d: None)
            assert client._listener_thread is not None
            assert client._listener_thread.daemon is True
            assert client._listening is True
            client.stop()
            assert client._listening is False
