"""Regression tests for OpenAI provider kwargs sanitization."""
from __future__ import annotations

import sys
import types

import pytest

from logos_adk.providers.openai import OpenAIProvider
from logos_adk.types import Message


class _FakeCreateRecorder:
    def __init__(self) -> None:
        self.calls: list[dict[str, object]] = []

    async def __call__(self, **kwargs):
        self.calls.append(kwargs)
        if kwargs.get("stream"):
            return _FakeStream()
        return types.SimpleNamespace(
            id="resp-1",
            model="gpt-4o-mini",
            usage=types.SimpleNamespace(prompt_tokens=3, completion_tokens=2),
            choices=[
                types.SimpleNamespace(
                    finish_reason="stop",
                    message=types.SimpleNamespace(
                        content="ok",
                        tool_calls=None,
                        model_extra=None,
                    ),
                )
            ],
        )


class _FakeStream:
    def __aiter__(self):
        async def _gen():
            yield types.SimpleNamespace(
                choices=[
                    types.SimpleNamespace(
                        delta=types.SimpleNamespace(content="hello"),
                    )
                ],
                usage=None,
            )
        return _gen()


class _FakeOpenAIClient:
    recorder = _FakeCreateRecorder()

    def __init__(self, **kwargs):
        self.kwargs = kwargs
        self.chat = types.SimpleNamespace(
            completions=types.SimpleNamespace(create=self.recorder)
        )


@pytest.fixture(autouse=True)
def _reset_openai_provider_pools():
    OpenAIProvider._client_pool.clear()
    OpenAIProvider._http_client_pool.clear()
    _FakeOpenAIClient.recorder.calls.clear()
    yield
    OpenAIProvider._client_pool.clear()
    OpenAIProvider._http_client_pool.clear()


@pytest.fixture(autouse=True)
def _fake_openai_module(monkeypatch):
    monkeypatch.setitem(sys.modules, "openai", types.SimpleNamespace(AsyncOpenAI=_FakeOpenAIClient))


@pytest.mark.asyncio
async def test_openai_provider_generate_filters_internal_runtime_kwargs():
    provider = OpenAIProvider(model="gpt-4o-mini", api_key="test-key")

    response = await provider.generate(
        [Message(role="user", content="hello")],
        correlation_id="corr-1",
        request_id="req-1",
        _trace_id="trace-1",
        run_id="run-1",
        temperature=0.3,
    )

    assert response.content == "ok"
    sent_kwargs = _FakeOpenAIClient.recorder.calls[-1]
    assert sent_kwargs["temperature"] == 0.3
    assert "correlation_id" not in sent_kwargs
    assert "request_id" not in sent_kwargs
    assert "_trace_id" not in sent_kwargs
    assert "run_id" not in sent_kwargs


@pytest.mark.asyncio
async def test_openai_provider_stream_filters_internal_runtime_kwargs():
    provider = OpenAIProvider(model="gpt-4o-mini", api_key="test-key")

    chunks = []
    async for chunk in provider.stream(
        [Message(role="user", content="hello")],
        correlation_id="corr-2",
        request_id="req-2",
        _trace_id="trace-2",
        session_id="sess-1",
        top_p=0.8,
    ):
        chunks.append(chunk)

    assert len(chunks) == 2
    sent_kwargs = _FakeOpenAIClient.recorder.calls[-1]
    assert sent_kwargs["stream"] is True
    assert sent_kwargs["top_p"] == 0.8
    assert "correlation_id" not in sent_kwargs
    assert "request_id" not in sent_kwargs
    assert "_trace_id" not in sent_kwargs
    assert "session_id" not in sent_kwargs
