"""Tests offline de comfyui_generate_styles_llm — sin red (ask_llm monkeypatcheado)."""
import os
import sys

sys.path.insert(0, os.path.dirname(__file__))

import comfyui_generate_styles_llm as mod
from comfyui_generate_styles_llm import (
    _extract_json_object,
    _validate,
    comfyui_generate_styles_llm,
    DEFAULT_NEGATIVE,
)


def test_extract_json_plano():
    txt = '{"a": {"prompt": "x", "negative_prompt": "y"}}'
    obj = _extract_json_object(txt)
    assert obj == {"a": {"prompt": "x", "negative_prompt": "y"}}


def test_extract_json_con_fence_y_prosa():
    txt = 'Aquí tienes:\n```json\n{"a": {"prompt": "x"}}\n```\nFin.'
    obj = _extract_json_object(txt)
    assert obj == {"a": {"prompt": "x"}}


def test_extract_json_corrupto_devuelve_none():
    assert _extract_json_object("no json aquí") is None
    assert _extract_json_object("") is None
    assert _extract_json_object("{roto") is None


def test_validate_descarta_invalidos_y_duplicados():
    obj = {
        "ok": {"prompt": "modificador", "negative_prompt": "n"},
        "sin_neg": {"prompt": "solo prompt"},
        "vacio": {"prompt": "   "},
        "dup": {"prompt": "x"},
        "no_dict": "string",
    }
    clean = _validate(obj, avoid={"dup"})
    assert set(clean) == {"ok", "sin_neg"}
    assert clean["sin_neg"]["negative_prompt"] == DEFAULT_NEGATIVE


def test_validate_quita_placeholder_prompt():
    obj = {"x": {"prompt": "cinematic, {prompt}, dramatic light"}}
    clean = _validate(obj, avoid=set())
    assert "{prompt}" not in clean["x"]["prompt"]
    assert clean["x"]["prompt"]


def test_error_path_ask_llm_lanza_devuelve_vacio(monkeypatch=None):
    # Simula ask_llm que revienta -> la función debe devolver {} sin propagar.
    def boom(*a, **k):
        raise RuntimeError("429 rate limit")

    orig = mod.ask_llm
    mod.ask_llm = boom
    try:
        out = comfyui_generate_styles_llm("cualquier categoría", n=5, prefix="z-")
        assert out == {}
    finally:
        mod.ask_llm = orig


def test_ask_llm_ausente_devuelve_vacio():
    orig = mod.ask_llm
    mod.ask_llm = None
    try:
        assert comfyui_generate_styles_llm("cat", n=3) == {}
    finally:
        mod.ask_llm = orig


def test_respuesta_valida_se_parsea():
    orig = mod.ask_llm
    mod.ask_llm = lambda *a, **k: '{"z-one": {"prompt": "neon glow, synthwave", "negative_prompt": "flat"}}'
    try:
        out = comfyui_generate_styles_llm("synthwave", n=1, prefix="z-")
        assert out == {"z-one": {"prompt": "neon glow, synthwave", "negative_prompt": "flat"}}
    finally:
        mod.ask_llm = orig


if __name__ == "__main__":
    for name, fn in sorted(globals().items()):
        if name.startswith("test_") and callable(fn):
            fn()
            print("PASS", name)
    print("OK")
