"""Tests for provider proxy configuration and client wiring."""
from __future__ import annotations

import sys
import types

import pytest

from logos_adk.agent import Agent


class _FakeOpenAIClient:
    instances: list[dict] = []

    def __init__(self, **kwargs):
        self.kwargs = kwargs
        type(self).instances.append(kwargs)
        self.chat = types.SimpleNamespace(
            completions=types.SimpleNamespace(create=self._create)
        )

    async def _create(self, **kwargs):
        raise AssertionError("network call not expected in proxy wiring test")


class _FakeAnthropicClient:
    instances: list[dict] = []

    def __init__(self, **kwargs):
        self.kwargs = kwargs
        type(self).instances.append(kwargs)
        self.messages = types.SimpleNamespace(create=self._create, stream=self._stream)

    async def _create(self, **kwargs):
        raise AssertionError("network call not expected in proxy wiring test")

    def _stream(self, **kwargs):
        raise AssertionError("stream call not expected in proxy wiring test")


@pytest.fixture(autouse=True)
def _reset_provider_pools():
    from logos_adk.providers.anthropic import AnthropicProvider
    from logos_adk.providers.openai import OpenAIProvider

    OpenAIProvider._client_pool.clear()
    OpenAIProvider._http_client_pool.clear()
    AnthropicProvider._client_pool.clear()
    AnthropicProvider._http_client_pool.clear()
    _FakeOpenAIClient.instances.clear()
    _FakeAnthropicClient.instances.clear()
    yield
    OpenAIProvider._client_pool.clear()
    OpenAIProvider._http_client_pool.clear()
    AnthropicProvider._client_pool.clear()
    AnthropicProvider._http_client_pool.clear()


def test_agent_provider_config_passes_proxy_to_openai_client(monkeypatch):
    fake_module = types.SimpleNamespace(AsyncOpenAI=_FakeOpenAIClient)
    monkeypatch.setitem(sys.modules, "openai", fake_module)

    agent = Agent("proxy-bot")
    from logos_adk.config import ProviderConfig

    agent._config.provider = ProviderConfig(
        type="openai",
        model="gpt-4o-mini",
        proxy="http://proxy.internal:8080",
        api_key="test-key",
    )

    provider = agent._create_provider_from_config()

    assert provider.proxy == "http://proxy.internal:8080"
    assert len(_FakeOpenAIClient.instances) == 1
    assert _FakeOpenAIClient.instances[0]["http_client"] is not None
    assert _FakeOpenAIClient.instances[0]["base_url"] is None


def test_agent_provider_config_passes_proxy_to_anthropic_client(monkeypatch):
    fake_module = types.SimpleNamespace(AsyncAnthropic=_FakeAnthropicClient)
    monkeypatch.setitem(sys.modules, "anthropic", fake_module)

    from logos_adk.config import ProviderConfig

    agent = Agent("proxy-bot")
    agent._config.provider = ProviderConfig(
        type="anthropic",
        model="claude-sonnet",
        proxy="http://proxy.internal:8080",
        api_key="test-key",
    )

    provider = agent._create_provider_from_config()

    assert provider.proxy == "http://proxy.internal:8080"
    assert len(_FakeAnthropicClient.instances) == 1
    assert _FakeAnthropicClient.instances[0]["http_client"] is not None


def test_openai_compatible_provider_uses_proxy_from_yaml_config(monkeypatch):
    fake_module = types.SimpleNamespace(AsyncOpenAI=_FakeOpenAIClient)
    monkeypatch.setitem(sys.modules, "openai", fake_module)

    from logos_adk.config import ProviderConfig

    agent = Agent("proxy-bot")
    agent._config.provider = ProviderConfig(
        type="openai-compatible",
        model="local-model",
        base_url="http://localhost:1234/v1",
        proxy="http://proxy.internal:8080",
        api_key="test-key",
    )

    provider = agent._create_provider_from_config()

    assert provider.proxy == "http://proxy.internal:8080"
    assert len(_FakeOpenAIClient.instances) == 1
    assert _FakeOpenAIClient.instances[0]["base_url"] == "http://localhost:1234/v1"


def test_agent_provider_config_builds_gemini_provider():
    from logos_adk.config import ProviderConfig
    from logos_adk.providers.gemini import GeminiProvider

    agent = Agent("proxy-bot")
    agent._config.provider = ProviderConfig(
        type="gemini",
        model="gemini-2.0-flash",
        proxy="http://proxy.internal:8080",
        api_key="test-key",
    )

    provider = agent._create_provider_from_config()

    assert isinstance(provider, GeminiProvider)
    assert provider.proxy == "http://proxy.internal:8080"


def test_agent_provider_config_builds_openai_responses_provider():
    from logos_adk.config import ProviderConfig
    from logos_adk.providers.openai_responses import OpenAIResponsesProvider

    agent = Agent("proxy-bot")
    agent._config.provider = ProviderConfig(
        type="openai-responses",
        model="gpt-4.1",
        proxy="http://proxy.internal:8080",
        api_key="test-key",
    )

    provider = agent._create_provider_from_config()

    assert isinstance(provider, OpenAIResponsesProvider)
    assert provider.proxy == "http://proxy.internal:8080"
