"""Tests for the Lemonade engine backend.

Validates that the ``/v1`` prefix is used correctly for models listing
and chat completions.
"""

from __future__ import annotations

import httpx
import pytest
import respx

from openjarvis.core.registry import EngineRegistry
from openjarvis.core.types import Message, Role
from openjarvis.engine._base import EngineConnectionError
from openjarvis.engine.openai_compat_engines import LemonadeEngine


@pytest.fixture()
def engine() -> LemonadeEngine:
    EngineRegistry.register_value("lemonade", LemonadeEngine)
    return LemonadeEngine(host="http://testhost:13305")


class TestLemonadeEngineBasics:
    def test_engine_id(self) -> None:
        assert LemonadeEngine.engine_id == "lemonade"

    def test_default_host(self) -> None:
        assert LemonadeEngine._default_host == "http://localhost:13305"

    def test_api_prefix(self) -> None:
        assert LemonadeEngine._api_prefix == "/v1"

    def test_registry_registration(self) -> None:
        EngineRegistry.register_value("lemonade", LemonadeEngine)
        assert EngineRegistry.get("lemonade") is LemonadeEngine

    def test_env_var_overrides_default_host(
        self,
        monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.setenv("LEMONADE_HOST", "http://env-lemonade:17777")
        engine = LemonadeEngine()
        try:
            assert engine._host == "http://env-lemonade:17777"
        finally:
            engine.close()


class TestLemonadeGenerate:
    def test_generate_uses_v1_prefix(self, engine: LemonadeEngine) -> None:
        with respx.mock:
            respx.post("http://testhost:13305/v1/chat/completions").mock(
                return_value=httpx.Response(
                    200,
                    json={
                        "choices": [
                            {
                                "message": {"content": "Hello!"},
                                "finish_reason": "stop",
                            }
                        ],
                        "usage": {
                            "prompt_tokens": 5,
                            "completion_tokens": 2,
                            "total_tokens": 7,
                        },
                        "model": "Qwen3-4B-Instruct",
                    },
                )
            )
            result = engine.generate(
                [Message(role=Role.USER, content="Hi")], model="Qwen3-4B-Instruct"
            )
        assert result["content"] == "Hello!"
        assert result["usage"]["total_tokens"] == 7

    def test_generate_connection_error(self, engine: LemonadeEngine) -> None:
        with respx.mock:
            respx.post("http://testhost:13305/v1/chat/completions").mock(
                side_effect=httpx.ConnectError("refused")
            )
            with pytest.raises(EngineConnectionError):
                engine.generate(
                    [Message(role=Role.USER, content="Hi")],
                    model="Qwen3-4B-Instruct",
                )


class TestLemonadeHealth:
    def test_health_true(self, engine: LemonadeEngine) -> None:
        with respx.mock:
            respx.get("http://testhost:13305/v1/models").mock(
                return_value=httpx.Response(200, json={"data": []})
            )
            assert engine.health() is True

    def test_health_false(self, engine: LemonadeEngine) -> None:
        with respx.mock:
            respx.get("http://testhost:13305/v1/models").mock(
                side_effect=httpx.ConnectError("refused")
            )
            assert engine.health() is False


class TestLemonadeListModels:
    def test_list_models_uses_v1_prefix(self, engine: LemonadeEngine) -> None:
        with respx.mock:
            respx.get("http://testhost:13305/v1/models").mock(
                return_value=httpx.Response(
                    200,
                    json={
                        "data": [
                            {"id": "Qwen3-4B-Instruct"},
                            {"id": "Llama-3.1-8B"},
                        ]
                    },
                )
            )
            assert engine.list_models() == ["Qwen3-4B-Instruct", "Llama-3.1-8B"]
