"""Tests fuer das Retry-Verhalten des OpenRouter-TTS (transiente leere/5xx-Antworten)."""

import asyncio

import httpx
import pytest

import app.providers.tts.openrouter as orm
from app.providers.tts.openrouter import OpenRouterTTSProvider

REQ = httpx.Request("POST", "https://openrouter.ai/api/v1/audio/speech")


def _run(coro):
    return asyncio.run(coro)


def _patch(monkeypatch, responses):
    """httpx-POST liefert nacheinander die vorgegebenen Antworten; kein echtes Sleep."""
    it = iter(responses)
    calls = {"n": 0}

    async def fake_post(self, url, **kw):
        calls["n"] += 1
        return next(it)

    async def no_sleep(*a, **k):
        pass

    monkeypatch.setattr(httpx.AsyncClient, "post", fake_post)
    monkeypatch.setattr(orm.asyncio, "sleep", no_sleep)
    return calls


def _provider():
    return OpenRouterTTSProvider("key", "some/model", "Zephyr")


def test_retries_on_empty_then_succeeds(monkeypatch):
    calls = _patch(monkeypatch, [
        httpx.Response(200, content=b"", request=REQ),       # transienter Aussetzer
        httpx.Response(200, content=b"AUDIO", request=REQ),  # dann echtes Audio
    ])
    assert _run(_provider().synthesize("Hallo")) == b"AUDIO"
    assert calls["n"] == 2


def test_4xx_raises_immediately_without_retry(monkeypatch):
    calls = _patch(monkeypatch, [
        httpx.Response(400, text="invalid voice", request=REQ),
    ])
    with pytest.raises(RuntimeError, match="400"):
        _run(_provider().synthesize("Hallo"))
    assert calls["n"] == 1  # kein Retry bei 4xx


def test_all_empty_raises_after_attempts(monkeypatch):
    calls = _patch(monkeypatch, [httpx.Response(200, content=b"", request=REQ)] * orm._MAX_ATTEMPTS)
    with pytest.raises(RuntimeError, match="empty audio content"):
        _run(_provider().synthesize("Hallo"))
    assert calls["n"] == orm._MAX_ATTEMPTS


def test_5xx_then_success(monkeypatch):
    calls = _patch(monkeypatch, [
        httpx.Response(503, text="upstream", request=REQ),
        httpx.Response(200, content=b"OK", request=REQ),
    ])
    assert _run(_provider().synthesize("Hallo")) == b"OK"
    assert calls["n"] == 2
