import asyncio
import pytest
from manteniment import TascaManteniment, tecnic_manteniment, monitor_sistema

@pytest.mark.asyncio
async def test_monitor_sistema_genera_ordres():
    """Test que verifica que el monitor genera el nombre correcte d'ordres."""
    cua = asyncio.PriorityQueue()
    total_ordres = 5

    # Executem el monitor
    await monitor_sistema(cua, total_ordres)

    # Verifiquem que s'han generat totes les ordres
    assert cua.qsize() == total_ordres

@pytest.mark.asyncio
async def test_monitor_sistema_ordres_amb_prioritat():
    """Test que verifica que les ordres generades tenen prioritats vàlides."""
    cua = asyncio.PriorityQueue()
    total_ordres = 10

    # Executem el monitor
    await monitor_sistema(cua, total_ordres)

    # Verifiquem que totes les ordres tenen prioritat 1 o 2
    for _ in range(total_ordres):
        tasca = await cua.get()
        assert tasca.prioritat in (1, 2)
        cua.task_done()

@pytest.mark.asyncio
async def test_monitor_sistema_cua_buida_inicial():
    """Test que verifica que la cua està buida inicialment."""
    cua = asyncio.PriorityQueue()

    # Executem el monitor amb 0 ordres
    await monitor_sistema(cua, 0)

    # Verifiquem que la cua està buida
    assert cua.empty()

@pytest.mark.asyncio
async def test_monitor_sistema_cua_plena():
    """Test que verifica el comportament de la cua quan està plena."""
    cua = asyncio.PriorityQueue(maxsize=2)
    total_ordres = 5

    # Posem dues tasques a la cua per omplir-la
    for _ in range(2):
        tasca = TascaManteniment(prioritat=1, id_maquina=1, temps_reparacio=0.1)
        await cua.put(tasca)

    # Iniciem el monitor en una tasca separada per evitar bloqueig
    monitor_task = asyncio.create_task(monitor_sistema(cua, total_ordres))

    # Esperem una mica per assegurar-nos que el monitor intenta posar més tasques
    await asyncio.sleep(0.1)

    # Verifiquem que la cua està plena
    assert cua.qsize() == 2

    # Cancel·lem el monitor
    monitor_task.cancel()
    try:
        await monitor_task
    except asyncio.CancelledError:
        pass
