"""Tests de estructura para comfyui_build_img2vid_workflow (funcion pura, SVD)."""

import os
import sys

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

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


def test_estructura_y_nodos_svd():
    wf = comfyui_build_img2vid_workflow("example.png")
    assert_api_format(wf)
    cts = class_types(wf)
    for ct in (
        "ImageOnlyCheckpointLoader",
        "LoadImage",
        "SVD_img2vid_Conditioning",
        "VideoLinearCFGGuidance",
        "KSampler",
        "VAEDecode",
        "SaveAnimatedWEBP",
    ):
        assert ct in cts, f"falta {ct} en SVD img2vid"
    # El checkpoint SVD es todo-en-uno cargado con el loader image-only.
    assert node_by_ct(wf, "ImageOnlyCheckpointLoader")["inputs"]["ckpt_name"] == (
        "VIDEO_svd.safetensors"
    )
    # La imagen base entra por LoadImage.
    assert node_by_ct(wf, "LoadImage")["inputs"]["image"] == "example.png"


def test_cableado_de_nodos():
    wf = comfyui_build_img2vid_workflow("example.png")
    cond = node_by_ct(wf, "SVD_img2vid_Conditioning")["inputs"]
    # clip_vision y vae salen del checkpoint image-only (outputs 1 y 2).
    assert cond["clip_vision"] == ["15", 1]
    assert cond["vae"] == ["15", 2]
    assert cond["init_image"] == ["23", 0]
    ks = node_by_ct(wf, "KSampler")["inputs"]
    # KSampler usa el MODEL post VideoLinearCFGGuidance y los 3 outputs del cond.
    assert ks["model"] == ["14", 0]
    assert ks["positive"] == ["12", 0]
    assert ks["negative"] == ["12", 1]
    assert ks["latent_image"] == ["12", 2]
    assert ks["denoise"] == 1.0
    # VideoLinearCFGGuidance toma el MODEL crudo del checkpoint.
    assert node_by_ct(wf, "VideoLinearCFGGuidance")["inputs"]["model"] == ["15", 0]


def test_params_se_reflejan():
    wf = comfyui_build_img2vid_workflow(
        "fox_front.png",
        width=768,
        height=448,
        video_frames=25,
        motion_bucket_id=200,
        fps=10,
        augmentation_level=0.2,
        steps=25,
        cfg=3.0,
        min_cfg=1.5,
        seed=7,
        filename_prefix="myclip",
    )
    cond = node_by_ct(wf, "SVD_img2vid_Conditioning")["inputs"]
    assert cond["width"] == 768 and cond["height"] == 448
    assert cond["video_frames"] == 25
    assert cond["motion_bucket_id"] == 200
    assert cond["fps"] == 10
    assert cond["augmentation_level"] == 0.2
    ks = node_by_ct(wf, "KSampler")["inputs"]
    assert ks["steps"] == 25 and ks["cfg"] == 3.0 and ks["seed"] == 7
    assert node_by_ct(wf, "VideoLinearCFGGuidance")["inputs"]["min_cfg"] == 1.5
    save = node_by_ct(wf, "SaveAnimatedWEBP")["inputs"]
    assert save["filename_prefix"] == "myclip"
    # SaveAnimatedWEBP declara fps como FLOAT en /object_info.
    assert save["fps"] == 10.0
    assert isinstance(save["fps"], float)


def test_determinista():
    a = comfyui_build_img2vid_workflow("example.png", seed=7)
    b = comfyui_build_img2vid_workflow("example.png", seed=7)
    assert a == b
