"""Tests de estructura, repunte y pureza para comfyui_inject_controlnet (funcion pura)."""

import os
import sys

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

import pytest

from ml.comfyui_build_txt2img_workflow import comfyui_build_txt2img_workflow
from ml.comfyui_inject_controlnet import comfyui_inject_controlnet
from _comfyui_wf_assert import assert_api_format, class_types, node_by_ct


def _base():
    return comfyui_build_txt2img_workflow("ck.safetensors", "POS", "NEG")


def test_inyecta_tres_nodos_y_repunta_positive():
    base = _base()
    inj = comfyui_inject_controlnet(base, "ctrl.png", "cn_canny.pth", strength=0.7)
    assert_api_format(inj)
    cts = class_types(inj)
    assert {"LoadImage", "ControlNetLoader", "ControlNetApply"} <= cts
    # El KSampler.positive ahora viene de un ControlNetApply.
    ks = node_by_ct(inj, "KSampler")
    pos_link = ks["inputs"]["positive"]
    assert inj[pos_link[0]]["class_type"] == "ControlNetApply"


def test_controlnetapply_toma_el_positivo_original():
    base = _base()
    # En el base, KSampler.positive apunta al CLIPTextEncode positivo (nodo "6").
    orig_pos = base["3"]["inputs"]["positive"]
    inj = comfyui_inject_controlnet(base, "ctrl.png", "cn_canny.pth")
    apply_node = node_by_ct(inj, "ControlNetApply")
    assert apply_node["inputs"]["conditioning"] == orig_pos
    # control_net e image apuntan al loader y al LoadImage.
    assert inj[apply_node["inputs"]["control_net"][0]]["class_type"] == "ControlNetLoader"
    assert inj[apply_node["inputs"]["image"][0]]["class_type"] == "LoadImage"


def test_respeta_strength_y_cn_name():
    inj = comfyui_inject_controlnet(_base(), "c.png", "mymodel.pth", strength=0.42)
    apply_node = node_by_ct(inj, "ControlNetApply")
    loader = node_by_ct(inj, "ControlNetLoader")
    load = node_by_ct(inj, "LoadImage")
    assert apply_node["inputs"]["strength"] == 0.42
    assert loader["inputs"]["control_net_name"] == "mymodel.pth"
    assert load["inputs"]["image"] == "c.png"


def test_no_muta_entrada():
    base = _base()
    snapshot = {k: dict(v) for k, v in base.items()}
    comfyui_inject_controlnet(base, "c.png", "m.pth")
    assert set(base) == set(snapshot)
    assert base["3"]["inputs"]["positive"] == snapshot["3"]["inputs"]["positive"]


def test_control_image_vacio_lanza():
    with pytest.raises(ValueError):
        comfyui_inject_controlnet(_base(), "", "m.pth")


def test_sin_ksampler_lanza():
    wf = {"4": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "x"}}}
    with pytest.raises(ValueError):
        comfyui_inject_controlnet(wf, "c.png", "m.pth")
