"""Tests for diffusion backend integration."""
from __future__ import annotations

import asyncio
import base64
import json

import httpx
import pytest

from logos_adk.diffusion import Automatic1111DiffusionBackend
from logos_adk.tools.artifacts import ArtifactToolkit


def test_automatic1111_backend_parses_txt2img_response():
    png_bytes = b"fake-png-image"
    expected_b64 = base64.b64encode(png_bytes).decode("ascii")
    captured: dict[str, object] = {}

    def handler(request: httpx.Request) -> httpx.Response:
        captured["url"] = str(request.url)
        captured["body"] = request.content.decode("utf-8")
        return httpx.Response(
            200,
            json={"images": [expected_b64], "info": '{"seed": 7}'},
        )

    client = httpx.AsyncClient(transport=httpx.MockTransport(handler))
    backend = Automatic1111DiffusionBackend(base_url="http://sd.example", client=client)
    result = asyncio.run(
        backend.generate_image(
            prompt="cinematic red scooter",
            negative_prompt="blurry",
            width=768,
            height=512,
            steps=32,
            guidance_scale=8.5,
            seed=7,
            sampler_name="Euler a",
        )
    )
    asyncio.run(client.aclose())

    assert captured["url"] == "http://sd.example/sdapi/v1/txt2img"
    assert json.loads(str(captured["body"]))["prompt"] == "cinematic red scooter"
    assert result.base64_data == expected_b64
    assert result.mime_type == "image/png"
    assert result.metadata["backend"] == "automatic1111"
    assert result.metadata["seed"] == 7
    assert result.metadata["sampler_name"] == "Euler a"


def test_automatic1111_backend_errors_when_images_missing():
    def handler(request: httpx.Request) -> httpx.Response:
        return httpx.Response(200, json={"images": []})

    client = httpx.AsyncClient(transport=httpx.MockTransport(handler))
    backend = Automatic1111DiffusionBackend(client=client)

    with pytest.raises(RuntimeError, match="returned no image payload"):
        asyncio.run(backend.generate_image(prompt="poster"))

    asyncio.run(client.aclose())


def test_artifact_toolkit_generates_diffusion_image_artifact(tmp_path, monkeypatch):
    png_b64 = base64.b64encode(b"png-data").decode("ascii")
    toolkit = ArtifactToolkit(root=str(tmp_path / "artifacts"))
    tools = {tool.name: tool for tool in toolkit.get_tools()}

    class FakeBackend:
        async def generate_image(self, **kwargs):
            return type(
                "Result",
                (),
                {
                    "base64_data": png_b64,
                    "mime_type": "image/png",
                    "metadata": {"backend": "automatic1111", "parameters": kwargs},
                },
            )()

    monkeypatch.setattr(
        "logos_adk.tools.artifacts.build_diffusion_backend",
        lambda **kwargs: FakeBackend(),
    )

    created = asyncio.run(
        tools["generate_diffusion_image_artifact"](
            name="hero-shot",
            prompt="bright marketplace banner",
            width=640,
            height=360,
            model="realvis",
        )
    )
    listed = asyncio.run(tools["list_artifacts"](kind="image"))

    assert created["name"] == "hero-shot"
    assert created["kind"] == "image"
    assert created["mime_type"] == "image/png"
    assert created["metadata"]["prompt"] == "bright marketplace banner"
    assert created["metadata"]["backend"] == "automatic1111"
    assert created["metadata"]["parameters"]["model"] == "realvis"
    assert listed[0]["id"] == created["id"]
