"""Tests de estructura/determinismo para comfyui_build_outpaint_asset_workflow (func pura, outpaint)."""

import os
import sys

import pytest

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

from ml.comfyui_build_outpaint_asset_workflow import comfyui_build_outpaint_asset_workflow
from _comfyui_wf_assert import assert_api_format, class_types, node_by_ct


def test_estructura_outpaint():
    wf = comfyui_build_outpaint_asset_workflow("bg.png", "more forest", right=256)
    assert_api_format(wf)
    cts = class_types(wf)
    for ct in ("CheckpointLoaderSimple", "LoadImage", "ImagePadForOutpaint",
               "VAEEncodeForInpaint", "CLIPTextEncode", "KSampler", "VAEDecode", "SaveImage"):
        assert ct in cts, f"falta nodo {ct}"
    # outpaint genera su mascara con el pad: NO usa LoadImageMask.
    assert "LoadImageMask" not in cts


def test_pad_cableado_a_vaeencode():
    # VAEEncodeForInpaint toma pixels de la IMAGE del pad y mask de la MASK del pad.
    wf = comfyui_build_outpaint_asset_workflow("bg.png", "sky", top=128)
    pad_id = next(nid for nid, n in wf.items() if n["class_type"] == "ImagePadForOutpaint")
    enc = node_by_ct(wf, "VAEEncodeForInpaint")["inputs"]
    assert enc["pixels"] == [pad_id, 0]
    assert enc["mask"] == [pad_id, 1]


def test_extensiones_redondeadas_a_8():
    # _round8 normaliza al multiplo de 8 mas cercano.
    wf = comfyui_build_outpaint_asset_workflow("bg.png", "p", right=10)
    pad = node_by_ct(wf, "ImagePadForOutpaint")["inputs"]
    assert pad["right"] == 8 and pad["left"] == 0 and pad["top"] == 0 and pad["bottom"] == 0


def test_sin_extension_lanza():
    # las cuatro extensiones a 0 (tras redondear) -> no hay nada que extender.
    with pytest.raises(ValueError):
        comfyui_build_outpaint_asset_workflow("bg.png", "p", left=3, right=2)


def test_feather_y_prompt():
    wf = comfyui_build_outpaint_asset_workflow("bg.png", "open sky", top=64, feather=30)
    assert node_by_ct(wf, "ImagePadForOutpaint")["inputs"]["feathering"] == 30
    pos = [n["inputs"]["text"] for n in wf.values()
           if n["class_type"] == "CLIPTextEncode" and "seamless extension" in n["inputs"].get("text", "")]
    assert pos and "open sky" in pos[0]


def test_lora_y_filename():
    wf = comfyui_build_outpaint_asset_workflow("bg.png", "p", right=64, lora="x.safetensors",
                                               filename_prefix="mio")
    assert "LoraLoader" in class_types(wf)
    assert node_by_ct(wf, "SaveImage")["inputs"]["filename_prefix"] == "mio"


def test_errores_vacios():
    with pytest.raises(ValueError):
        comfyui_build_outpaint_asset_workflow("", "p", right=64)
    with pytest.raises(ValueError):
        comfyui_build_outpaint_asset_workflow("bg.png", "", right=64)


def test_determinista():
    a = comfyui_build_outpaint_asset_workflow("bg.png", "forest", right=256, seed=7)
    b = comfyui_build_outpaint_asset_workflow("bg.png", "forest", right=256, seed=7)
    assert a == b
