from itertools import product
from agents.roles import AGENTS
from datetime import datetime

def test_agents_on_prompt(model_class, prompt: str, agents: list, param_grid: dict, fixed_params: dict = None):
    """
    Teste les agents sur un prompt donné avec différentes combinaisons de paramètres
    model_class: Classe du modèle LLM à utiliser
    prompt: Prompt à tester
    agents: Liste des agents à tester
    param_grid: Grille de paramètres à tester
    fixed_params: Paramètres fixes à appliquer à tous les tests
    """

    if fixed_params is None:
        fixed_params = {} 
        
    #Générer toutes les combinaisons de paramètres à tester
    keys = list(param_grid.keys())
    values = list(param_grid.values())
    combinations = list(product(*values))
    
    print(f"[TEST STARTED] {len(agents)} agents, {len(combinations)} combinaisons, total; {len(agents) * len(combinations)} tests")
    
    for agent_name in agents:
        if agent_name not in AGENTS:
            print(f"[Skipped] Agent inconnu : {agent_name}")
            continue
        
        for combo in combinations:
            #instancier un modèle neuf à chaque test(préserve isolation)
            model = model_class()
            
            # Aplliquer le rôle de l'agent
            model.set_role(agent_name, AGENTS[agent_name])
            
            # Fusionner les paramètres (params agent < combo test < fixed)
            combo_params = dict(zip(keys, combo))
            model.params.update(combo_params)
            model.params.update(fixed_params)
            
            #Affichage console
            ts = datetime.now().strftime("%H:%M:%S")
            print(f"[{ts}] -> Agent: {agent_name} | Combo: {combo_params}")
            
            try:
                model.generate(prompt)
            except Exception as e:
                print(f"[Erreur] {e}")
        
    print("[TEST COMPLET]")