# Path: PW_explorer/Input_Parsers/Meta_Data_Parser/meta_data_parser.py
# META_DATA_GRAPHVIZ_GRAPH_DEF_KEYWORD = 'graph'
# 
# META_DATA_GRAPHVIZ_NODE_DEF_KEYWORD = 'node'
# 
# META_DATA_GRAPHVIZ_EDGE_DEF_KEYWORD = 'edge'
# 
# META_DATA_GRAPHVIZ_EDGE_HEAD_IDX_DEF_KEYWORD = 'head'
# 
# META_DATA_GRAPHVIZ_EDGE_TAIL_IDX_DEF_KEYWORD = 'tail'
# 
# META_DATA_GRAPHVIZ_NODE_ID_IDX_DEF_KEYWORD = 'node_id'
# 
# META_DATA_GRAPHVIZ_STYLES_KEYWORD = 'styles'
# 
# META_DATA_GRAPHVIZ_STYLE_PROPERTY_ARG_IDX_TYPE = 'arg_idx'
# 
# META_DATA_GRAPHVIZ_ORD_KEYWORD = 'ord'
# 
# META_DATA_GRAPHVIZ_GRAPH_TYPE = 'graph_type'
# 
# META_DATA_GRAPHVIZ_DIRECTED_KEYWORD = 'directed'
# 
# META_DATA_GRAPHVIZ_UNDIRECTED_KEYWORD = 'undirected'


import networkx as nx
from ..Input_Parsers.Meta_Data_Parser.meta_data_parser import (
    META_DATA_GRAPHVIZ_GRAPH_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_NODE_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_EDGE_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_EDGE_HEAD_IDX_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_EDGE_TAIL_IDX_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_NODE_ID_IDX_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_STYLES_KEYWORD,
    META_DATA_GRAPHVIZ_STYLE_PROPERTY_ARG_IDX_TYPE,
    META_DATA_GRAPHVIZ_ORD_KEYWORD,
    META_DATA_GRAPHVIZ_GRAPH_TYPE,
    META_DATA_GRAPHVIZ_DIRECTED_KEYWORD,
    META_DATA_GRAPHVIZ_UNDIRECTED_KEYWORD,
)



def build_nx_from_metadata(pw_rel_dfs: dict, graphviz_meta_data: dict):

    graph_type = graphviz_meta_data[META_DATA_GRAPHVIZ_GRAPH_DEF_KEYWORD][META_DATA_GRAPHVIZ_GRAPH_TYPE]
    if graph_type == META_DATA_GRAPHVIZ_UNDIRECTED_KEYWORD:
        G = nx.Graph()
    elif graph_type == META_DATA_GRAPHVIZ_DIRECTED_KEYWORD:
        G = nx.DiGraph()
    else:
        print("Unrecognized {} attribute. Choose one of ({})".
              format(META_DATA_GRAPHVIZ_GRAPH_TYPE,
                     ", ".join([META_DATA_GRAPHVIZ_UNDIRECTED_KEYWORD, META_DATA_GRAPHVIZ_DIRECTED_KEYWORD])))
        return None

    graph_styles = graphviz_meta_data[META_DATA_GRAPHVIZ_GRAPH_DEF_KEYWORD][META_DATA_GRAPHVIZ_STYLES_KEYWORD]
    for prop_name, prop_type, prop_value in graph_styles:
        G.graph[prop_name] = prop_value

    sort_by_ord_key = lambda x: x[1][META_DATA_GRAPHVIZ_ORD_KEYWORD]

    for edge_rel_name, edge_rel_details in sorted(graphviz_meta_data[META_DATA_GRAPHVIZ_EDGE_DEF_KEYWORD].items(),
                                                  key=sort_by_ord_key):
        if edge_rel_name in pw_rel_dfs:
            rel_df = pw_rel_dfs[edge_rel_name]

# Path: PW_explorer/Input_Parsers/Meta_Data_Parser/meta_data_parser.py
# META_DATA_GRAPHVIZ_GRAPH_DEF_KEYWORD = 'graph'
# 
# META_DATA_GRAPHVIZ_NODE_DEF_KEYWORD = 'node'
# 
# META_DATA_GRAPHVIZ_EDGE_DEF_KEYWORD = 'edge'
# 
# META_DATA_GRAPHVIZ_EDGE_HEAD_IDX_DEF_KEYWORD = 'head'
# 
# META_DATA_GRAPHVIZ_EDGE_TAIL_IDX_DEF_KEYWORD = 'tail'
# 
# META_DATA_GRAPHVIZ_NODE_ID_IDX_DEF_KEYWORD = 'node_id'
# 
# META_DATA_GRAPHVIZ_STYLES_KEYWORD = 'styles'
# 
# META_DATA_GRAPHVIZ_STYLE_PROPERTY_ARG_IDX_TYPE = 'arg_idx'
# 
# META_DATA_GRAPHVIZ_ORD_KEYWORD = 'ord'
# 
# META_DATA_GRAPHVIZ_GRAPH_TYPE = 'graph_type'
# 
# META_DATA_GRAPHVIZ_DIRECTED_KEYWORD = 'directed'
# 
# META_DATA_GRAPHVIZ_UNDIRECTED_KEYWORD = 'undirected'


# Path: PW_explorer/Custom_Visualization_Functions/graphviz_meta_data_based_visualization.py
import networkx as nx
from ..Input_Parsers.Meta_Data_Parser.meta_data_parser import (
    META_DATA_GRAPHVIZ_GRAPH_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_NODE_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_EDGE_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_EDGE_HEAD_IDX_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_EDGE_TAIL_IDX_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_NODE_ID_IDX_DEF_KEYWORD,
    META_DATA_GRAPHVIZ_STYLES_KEYWORD,
    META_DATA_GRAPHVIZ_STYLE_PROPERTY_ARG_IDX_TYPE,
    META_DATA_GRAPHVIZ_ORD_KEYWORD,
    META_DATA_GRAPHVIZ_GRAPH_TYPE,
    META_DATA_GRAPHVIZ_DIRECTED_KEYWORD,
    META_DATA_GRAPHVIZ_UNDIRECTED_KEYWORD,
)




def build_nx_from_metadata(pw_rel_dfs: dict, graphviz_meta_data: dict):

    graph_type = graphviz_meta_data[META_DATA_GRAPHVIZ_GRAPH_DEF_KEYWORD][META_DATA_GRAPHVIZ_GRAPH_TYPE]
    if graph_type == META_DATA_GRAPHVIZ_UNDIRECTED_KEYWORD:
        G = nx.Graph()
    elif graph_type == META_DATA_GRAPHVIZ_DIRECTED_KEYWORD:
        G = nx.DiGraph()
    else:
        print("Unrecognized {} attribute. Choose one of ({})".
              format(META_DATA_GRAPHVIZ_GRAPH_TYPE,
                     ", ".join([META_DATA_GRAPHVIZ_UNDIRECTED_KEYWORD, META_DATA_GRAPHVIZ_DIRECTED_KEYWORD])))
        return None

    graph_styles = graphviz_meta_data[META_DATA_GRAPHVIZ_GRAPH_DEF_KEYWORD][META_DATA_GRAPHVIZ_STYLES_KEYWORD]
    for prop_name, prop_type, prop_value in graph_styles:
        G.graph[prop_name] = prop_value

    sort_by_ord_key = lambda x: x[1][META_DATA_GRAPHVIZ_ORD_KEYWORD]

    for edge_rel_name, edge_rel_details in sorted(graphviz_meta_data[META_DATA_GRAPHVIZ_EDGE_DEF_KEYWORD].items(),
                                                  key=sort_by_ord_key):
        if edge_rel_name in pw_rel_dfs:
            rel_df = pw_rel_dfs[edge_rel_name]

            edge_head_attr_name = rel_df.columns[edge_rel_details[META_DATA_GRAPHVIZ_EDGE_HEAD_IDX_DEF_KEYWORD] + 1]