# standard
# third party
import pytest

# custom
from sunwaee.modules.gen.engine.factory import get_engine
from sunwaee.modules.gen.engine.providers.anthropic import AnthropicEngine
from sunwaee.modules.gen.engine.providers.google import GoogleEngine
from sunwaee.modules.gen.engine.providers.openai import OpenAIEngine

### HELPERS


def _monkeypatch_env(monkeypatch, provider: str, key: str = "env-key"):
    monkeypatch.setenv(f"{provider.upper()}_API_KEY", key)


def test_get_engine_anthropic():
    engine = get_engine("anthropic", "claude-3-5-haiku", "key")
    assert isinstance(engine, AnthropicEngine)
    assert engine.model == "claude-3-5-haiku"


def test_get_engine_google():
    engine = get_engine("google", "gemini-2.0-flash", "key")
    assert isinstance(engine, GoogleEngine)
    assert engine.model == "gemini-2.0-flash"


def test_get_engine_openai():
    engine = get_engine("openai", "gpt-4o", "key")
    assert isinstance(engine, OpenAIEngine)
    assert engine.base_url == "https://api.openai.com/v1"


def test_get_engine_deepseek():
    engine = get_engine("deepseek", "deepseek-reasoner", "key")
    assert isinstance(engine, OpenAIEngine)
    assert "deepseek" in engine.base_url


def test_get_engine_moonshot():
    engine = get_engine("moonshot", "moonshot-v1-8k", "key")
    assert isinstance(engine, OpenAIEngine)
    assert "moonshot" in engine.base_url


def test_get_engine_xai():
    engine = get_engine("xai", "grok-2", "key")
    assert isinstance(engine, OpenAIEngine)
    assert "x.ai" in engine.base_url


def test_get_engine_case_insensitive():
    engine = get_engine("Anthropic", "claude-3-5-haiku", "key")
    assert isinstance(engine, AnthropicEngine)

    engine = get_engine("GOOGLE", "gemini-2.0-flash", "key")
    assert isinstance(engine, GoogleEngine)


def test_get_engine_max_tokens():
    engine = get_engine("anthropic", "claude-3-5-haiku", "key", max_tokens=1024)
    assert engine.max_tokens == 1024


def test_get_engine_unknown_provider():
    with pytest.raises(ValueError, match="Unknown provider"):
        get_engine("banana", "some-model", "key")


### API KEY RESOLUTION


def test_get_engine_api_key_from_env(monkeypatch):
    _monkeypatch_env(monkeypatch, "anthropic")
    engine = get_engine("anthropic", "claude-3-5-haiku")
    assert isinstance(engine, AnthropicEngine)
    assert engine.api_key == "env-key"


def test_get_engine_explicit_key_takes_precedence(monkeypatch):
    _monkeypatch_env(monkeypatch, "anthropic", key="env-key")
    engine = get_engine("anthropic", "claude-3-5-haiku", api_key="explicit-key")
    assert engine.api_key == "explicit-key"


def test_get_engine_no_key_raises(monkeypatch):
    monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False)
    with pytest.raises(ValueError, match="ANTHROPIC_API_KEY"):
        get_engine("anthropic", "claude-3-5-haiku")
