"""Tests para pg_list_tables.

Requieren un PostgreSQL real. Si PG_TEST_DSN no esta definida, los tests que tocan
la DB se saltan. Cada test crea una tabla con nombre aleatorio y la elimina.

    PG_TEST_DSN="postgresql://user:pass@localhost:5433/trends" \
        python/.venv/bin/python3 -m pytest python/functions/infra/pg_list_tables_test.py
"""

import os
import sys
import uuid

import pytest

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from infra.pg_list_tables import pg_list_tables  # noqa: E402

PG_TEST_DSN = os.environ.get("PG_TEST_DSN")
requires_pg = pytest.mark.skipif(
    not PG_TEST_DSN, reason="PG_TEST_DSN no definido: se omiten los tests de Postgres"
)


@pytest.fixture
def temp_table():
    """Crea una tabla conocida y la elimina al terminar."""
    import psycopg2

    name = "pg_list_t_" + uuid.uuid4().hex[:12]
    conn = psycopg2.connect(PG_TEST_DSN)
    try:
        with conn.cursor() as cur:
            cur.execute(
                f"CREATE TABLE {name} "
                f"(id INTEGER NOT NULL, label TEXT, ts TIMESTAMP)"
            )
        conn.commit()
    finally:
        conn.close()

    yield name

    conn = psycopg2.connect(PG_TEST_DSN)
    try:
        with conn.cursor() as cur:
            cur.execute(f"DROP TABLE IF EXISTS {name}")
        conn.commit()
    finally:
        conn.close()


def test_skip_sin_pg_test_dsn():
    """skip sin PG_TEST_DSN."""
    if not PG_TEST_DSN:
        pytest.skip("PG_TEST_DSN no definido")
    assert PG_TEST_DSN


@requires_pg
def test_lista_tabla_creada_con_sus_columnas(temp_table):
    """lista tabla creada con sus columnas."""
    res = pg_list_tables(PG_TEST_DSN, schema="public")
    assert res["status"] == "ok"
    assert res["schema"] == "public"
    found = [t for t in res["tables"] if t["name"] == temp_table]
    assert len(found) == 1
    col_names = [c["name"] for c in found[0]["columns"]]
    assert col_names == ["id", "label", "ts"]  # orden por posicion ordinal


@requires_pg
def test_reporta_nullable_correctamente(temp_table):
    """reporta nullable correctamente."""
    res = pg_list_tables(PG_TEST_DSN, schema="public")
    cols = {
        c["name"]: c
        for t in res["tables"]
        if t["name"] == temp_table
        for c in t["columns"]
    }
    assert cols["id"]["nullable"] is False   # NOT NULL
    assert cols["label"]["nullable"] is True
    assert cols["id"]["type"] == "integer"


@requires_pg
def test_schema_inexistente_devuelve_lista_vacia():
    """schema inexistente devuelve lista vacia (no error)."""
    res = pg_list_tables(PG_TEST_DSN, schema="no_existe_" + uuid.uuid4().hex[:8])
    assert res["status"] == "ok"
    assert res["tables"] == []
