"""Tests para coerce_types."""

import sys
import os
from datetime import datetime, timezone

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

from coerce_types import coerce_types


def test_string_42_a_int_42():
    result, warnings = coerce_types({"n": "42"}, {"n": "int"})
    assert result["n"] == 42
    assert isinstance(result["n"], int)
    assert warnings == []


def test_string_3_14_a_float_3_14():
    result, warnings = coerce_types({"x": "3.14"}, {"x": "float"})
    assert abs(result["x"] - 3.14) < 1e-9
    assert warnings == []


def test_string_true_a_bool_true():
    result, warnings = coerce_types({"flag": "true"}, {"flag": "bool"})
    assert result["flag"] is True
    assert warnings == []

    result2, _ = coerce_types({"flag": "yes"}, {"flag": "bool"})
    assert result2["flag"] is True

    result3, _ = coerce_types({"flag": "1"}, {"flag": "bool"})
    assert result3["flag"] is True

    result4, _ = coerce_types({"flag": "false"}, {"flag": "bool"})
    assert result4["flag"] is False


def test_string_iso8601_a_datetime():
    result, warnings = coerce_types(
        {"ts": "2024-01-15T10:30:00Z"}, {"ts": "datetime"}
    )
    assert isinstance(result["ts"], datetime)
    assert result["ts"].year == 2024
    assert result["ts"].month == 1
    assert result["ts"].day == 15
    assert warnings == []


def test_coercion_fallida_genera_warning_sin_crash():
    result, warnings = coerce_types({"n": "not-a-number"}, {"n": "int"})
    # mantiene el original
    assert result["n"] == "not-a-number"
    assert len(warnings) == 1
    assert "n" in warnings[0]


def test_dict_con_mix_de_tipos_ya_correctos_y_strings():
    data = {"a": "10", "b": 3.14, "c": True, "d": "hello"}
    schema = {"a": "int", "b": "float", "c": "bool", "d": "str"}
    result, warnings = coerce_types(data, schema)
    assert result["a"] == 10
    assert abs(result["b"] - 3.14) < 1e-9
    assert result["c"] is True
    assert result["d"] == "hello"
    assert warnings == []


def test_campo_ausente_en_schema_pass_through_sin_tocar():
    data = {"a": "42", "b": [1, 2, 3]}
    schema = {"a": "int"}  # "b" no esta en schema
    result, warnings = coerce_types(data, schema)
    assert result["a"] == 42
    assert result["b"] == [1, 2, 3]
    assert warnings == []


def test_string_lista_a_list_str():
    result, warnings = coerce_types(
        {"tags": "python, go, bash"}, {"tags": "list[str]"}
    )
    assert result["tags"] == ["python", "go", "bash"]
    assert warnings == []
