#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script d'analyse de la structure du graphe DOT pour comprendre
comment intégrer l'ISG dans le générateur de template.
"""

import os
from pathlib import Path
from networkx.drawing.nx_agraph import read_dot

# Chemins
BASE_DIR = Path(__file__).resolve().parent
GRAPH_PATH = BASE_DIR / "graphe.dot"

def analyze_graph_structure(dot_path):
    """Analyse la structure du graphe et affiche ses caractéristiques."""
    print(f"Analyse du fichier: {dot_path}")
    
    # Lire le graphe
    G = read_dot(dot_path)
    
    # Informations de base
    print(f"Nombre total de nœuds: {len(G.nodes())}")
    print(f"Nombre total d'arêtes: {len(G.edges())}")
    
    # Analyse des attributs des nœuds
    node_attrs = {}
    for node, attrs in G.nodes(data=True):
        for key in attrs:
            if key not in node_attrs:
                node_attrs[key] = set()
            node_attrs[key].add(attrs[key])
    
    print("\nAttributs des nœuds:")
    for attr, values in node_attrs.items():
        print(f"- {attr}: {len(values)} valeurs différentes")
        if len(values) < 20:  # Afficher seulement si le nombre de valeurs est raisonnable
            print(f"  Valeurs: {', '.join(sorted(values))}")
    
    # Analyse des niveaux (si l'attribut existe)
    if 'level' in node_attrs:
        print("\nAnalyse par niveau:")
        levels = {}
        for node, attrs in G.nodes(data=True):
            if 'level' in attrs:
                level = attrs['level']
                if level not in levels:
                    levels[level] = []
                levels[level].append(node)
        
        for level, nodes in sorted(levels.items()):
            print(f"- Niveau {level}: {len(nodes)} nœuds")
            # Afficher quelques exemples
            if len(nodes) < 5:
                print(f"  Exemples: {', '.join(nodes)}")
            else:
                print(f"  Exemples: {', '.join(nodes[:3])}... (et {len(nodes)-3} autres)")
    
    # Analyse des attributs ISG
    print("\nRecherche des attributs ISG:")
    isg_nodes = []
    for node, attrs in G.nodes(data=True):
        if 'isg' in attrs:
            isg_nodes.append((node, attrs['isg']))
    
    if isg_nodes:
        print(f"- {len(isg_nodes)} nœuds avec attribut ISG")
        print("  Exemples:")
        for node, isg in isg_nodes[:5]:
            print(f"  - {node}: ISG = {isg}")
    else:
        print("- Aucun nœud avec attribut ISG trouvé")
    
    # Analyse des connexions pour les nœuds critiques (IHH)
    print("\nAnalyse des nœuds avec IHH:")
    ihh_nodes = []
    for node, attrs in G.nodes(data=True):
        if 'ihh_pays' in attrs or 'ihh_acteurs' in attrs:
            ihh_value_pays = attrs.get('ihh_pays', 'N/A') 
            ihh_value_acteurs = attrs.get('ihh_acteurs', 'N/A')
            ihh_nodes.append((node, ihh_value_pays, ihh_value_acteurs))
    
    if ihh_nodes:
        print(f"- {len(ihh_nodes)} nœuds avec attributs IHH")
        print("  Exemples:")
        for node, ihh_pays, ihh_acteurs in ihh_nodes[:5]:
            print(f"  - {node}: IHH pays = {ihh_pays}, IHH acteurs = {ihh_acteurs}")
            
            # Analyser les connexions de ce nœud
            print(f"    Connexions sortantes:")
            out_edges = list(G.out_edges(node))
            if out_edges:
                for i, (_, target) in enumerate(out_edges[:3]):
                    print(f"    - Vers {target}")
                if len(out_edges) > 3:
                    print(f"    - ... et {len(out_edges)-3} autres")
            else:
                print("    - Aucune connexion sortante")
                
            print(f"    Connexions entrantes:")
            in_edges = list(G.in_edges(node))
            if in_edges:
                for i, (source, _) in enumerate(in_edges[:3]):
                    print(f"    - Depuis {source}")
                if len(in_edges) > 3:
                    print(f"    - ... et {len(in_edges)-3} autres")
            else:
                print("    - Aucune connexion entrante")
    else:
        print("- Aucun nœud avec attributs IHH trouvé")

    # Vérifier si un nœud a un attribut de niveau 99 (ISG supposé)
    print("\nRecherche des nœuds de niveau 99 (ISG):")
    level_99_nodes = []
    for node, attrs in G.nodes(data=True):
        if attrs.get('level') == '99':
            level_99_nodes.append(node)
    
    if level_99_nodes:
        print(f"- {len(level_99_nodes)} nœuds de niveau 99")
        print("  Exemples:")
        for node in level_99_nodes[:5]:
            print(f"  - {node}")
            # Analyser les connexions de ce nœud
            print(f"    Connexions entrantes:")
            in_edges = list(G.in_edges(node))
            if in_edges:
                for i, (source, _) in enumerate(in_edges[:3]):
                    print(f"    - Depuis {source}")
                if len(in_edges) > 3:
                    print(f"    - ... et {len(in_edges)-3} autres")
            else:
                print("    - Aucune connexion entrante")
    else:
        print("- Aucun nœud de niveau 99 trouvé")
    
def check_isg_paths(dot_path):
    """Vérifie les chemins entre les nœuds critiques (IHH) et les nœuds ISG."""
    print("\nAnalyse des chemins entre nœuds IHH et nœuds ISG:")
    
    # Lire le graphe
    G = read_dot(dot_path)
    
    # Identifier les nœuds avec IHH
    ihh_nodes = []
    for node, attrs in G.nodes(data=True):
        ihh_pays = attrs.get('ihh_pays', 0)
        ihh_acteurs = attrs.get('ihh_acteurs', 0)
        try:
            ihh_pays = float(ihh_pays)
            ihh_acteurs = float(ihh_acteurs)
            if ihh_pays > 25 or ihh_acteurs > 25:  # Seuil critique
                ihh_nodes.append(node)
        except (ValueError, TypeError):
            pass
    
    if not ihh_nodes:
        print("- Aucun nœud IHH critique trouvé")
        return
        
    print(f"- {len(ihh_nodes)} nœuds IHH critiques identifiés")
    
    # Pour chaque nœud IHH critique, chercher des chemins vers des nœuds ISG
    for node in ihh_nodes[:5]:  # Limiter à 5 exemples
        print(f"\n  Analyse des chemins pour {node}:")
        
        # Analyser les voisins directs
        successors = list(G.successors(node))
        print(f"  - {len(successors)} successeurs directs")
        
        if successors:
            for succ in successors[:3]:
                print(f"    - Vers {succ}")
                
                # Vérifier les attributs de ce successeur
                succ_attrs = G.nodes[succ]
                print(f"      Attributs: {', '.join(f'{k}={v}' for k, v in succ_attrs.items() if k in ['level', 'isg'])}")
                
                # Chercher les successeurs de niveau 2
                succ2 = list(G.successors(succ))
                print(f"      {len(succ2)} successeurs de niveau 2")
                
                if succ2:
                    for s2 in succ2[:2]:
                        print(f"        - Vers {s2}")
                        s2_attrs = G.nodes[s2]
                        print(f"          Attributs: {', '.join(f'{k}={v}' for k, v in s2_attrs.items() if k in ['level', 'isg'])}")
                        
                        # Chercher encore plus loin si nécessaire
                        succ3 = list(G.successors(s2))
                        print(f"          {len(succ3)} successeurs de niveau 3")
                        
                        if succ3:
                            for s3 in succ3[:2]:
                                print(f"            - Vers {s3}")
                                s3_attrs = G.nodes[s3]
                                print(f"              Attributs: {', '.join(f'{k}={v}' for k, v in s3_attrs.items() if k in ['level', 'isg'])}")

def main():
    """Fonction principale."""
    print("=== Analyse de la structure du graphe ===")
    analyze_graph_structure(GRAPH_PATH)
    
    print("\n=== Analyse des chemins entre nœuds critiques et ISG ===")
    check_isg_paths(GRAPH_PATH)

if __name__ == "__main__":
    main()