"""Tests para ModelRef y LoraRef — instanciación, dump y validación."""

import json
import sys

# Importar desde el subdirectorio ml directamente para evitar colisiones de tipos
# entre ml.model_ref.ModelRef y model_ref.ModelRef en pydantic.
sys.path.insert(0, "python/functions/ml")

import pytest

from lora_ref import LoraRef
from model_ref import ModelRef


# ---------------------------------------------------------------------------
# ModelRef
# ---------------------------------------------------------------------------


def test_model_ref_instancia_ok():
    """ModelRef instancia sin errores"""
    m = ModelRef(name="stabilityai/sdxl-base-1.0", model_type="sdxl")
    assert m.name == "stabilityai/sdxl-base-1.0"
    assert m.model_type == "sdxl"


def test_model_ref_quantization_default_fp16():
    """quantization default es fp16"""
    m = ModelRef(name="runwayml/stable-diffusion-v1-5", model_type="sd15")
    assert m.quantization == "fp16"


def test_model_ref_quantization_override():
    """quantization se puede cambiar a otro valor válido"""
    m = ModelRef(name="some/model", model_type="flux_dev", quantization="bf16")
    assert m.quantization == "bf16"


def test_model_ref_path_default_none():
    """path es None por defecto"""
    m = ModelRef(name="some/model", model_type="sd15")
    assert m.path is None


def test_model_ref_path_set():
    """path se puede especificar"""
    m = ModelRef(name="some/model", model_type="sd15", path="/models/sd15.safetensors")
    assert m.path == "/models/sd15.safetensors"


def test_model_ref_dump():
    """model_dump devuelve dict con las claves esperadas"""
    try:
        from pydantic import BaseModel
    except ImportError:
        pytest.skip("pydantic no disponible")

    m = ModelRef(name="some/model", model_type="sdxl", quantization="q8_0")
    d = m.model_dump()
    assert isinstance(d, dict)
    assert d["name"] == "some/model"
    assert d["model_type"] == "sdxl"
    assert d["quantization"] == "q8_0"


def test_model_ref_validate_roundtrip():
    """roundtrip model_dump_json / model_validate ok"""
    try:
        from pydantic import BaseModel
    except ImportError:
        pytest.skip("pydantic no disponible")

    m = ModelRef(name="some/model", model_type="sd3", quantization="fp32")
    raw = json.loads(m.model_dump_json())
    m2 = ModelRef.model_validate(raw)
    assert m2.name == m.name
    assert m2.model_type == m.model_type
    assert m2.quantization == m.quantization


# ---------------------------------------------------------------------------
# LoraRef
# ---------------------------------------------------------------------------


def test_lora_ref_instancia_ok():
    """LoraRef instancia con path obligatorio"""
    lr = LoraRef(path="/loras/anime.safetensors")
    assert lr.path == "/loras/anime.safetensors"


def test_lora_ref_weight_default_1():
    """LoraRef weight default es 1.0"""
    lr = LoraRef(path="/loras/style.safetensors")
    assert lr.weight == 1.0


def test_lora_ref_weight_override():
    """LoraRef weight se puede cambiar"""
    lr = LoraRef(path="/loras/style.safetensors", weight=0.7)
    assert lr.weight == 0.7


def test_lora_ref_scale_default_none():
    """LoraRef scale default es None"""
    lr = LoraRef(path="/loras/x.safetensors")
    assert lr.scale is None


def test_lora_ref_dump():
    """LoraRef model_dump devuelve dict con las claves esperadas"""
    try:
        from pydantic import BaseModel
    except ImportError:
        pytest.skip("pydantic no disponible")

    lr = LoraRef(path="/loras/x.safetensors", weight=0.8, scale=0.9)
    d = lr.model_dump()
    assert d["path"] == "/loras/x.safetensors"
    assert d["weight"] == 0.8
    assert d["scale"] == 0.9


def test_lora_ref_validate_roundtrip():
    """roundtrip dump / validate ok"""
    try:
        from pydantic import BaseModel
    except ImportError:
        pytest.skip("pydantic no disponible")

    lr = LoraRef(path="/loras/x.safetensors", weight=0.5)
    raw = json.loads(lr.model_dump_json())
    lr2 = LoraRef.model_validate(raw)
    assert lr2.path == lr.path
    assert lr2.weight == lr.weight
