# -*- coding: utf-8 -*-

import json
import pdb
import os
from os.path import join as pj
import networkx as nx
import pandas as pd
from networkx.readwrite.json_graph import  node_link_data


def chain():

    g = nx.Graph()

    # Horizontal

    for i in range(11, 15):
        g.add_edge(i, i + 1)

    for i in range(7, 10):
        g.add_edge(i, i + 1)

    for i in range(4, 6):
        g.add_edge(i, i + 1)

    for i in range(2, 3):
        g.add_edge(i, i + 1)

    g.add_node(1)


    # Trans height

    g.add_edge(1, 2)
    g.add_edge(1, 3)

    g.add_edge(2, 4)
    g.add_edge(2, 5)
    g.add_edge(3, 5)
    g.add_edge(3, 6)

    g.add_edge(4, 7)
    g.add_edge(4, 8)
    g.add_edge(5, 8)
    g.add_edge(5, 9)
    g.add_edge(6, 9)
    g.add_edge(6, 10)

    g.add_edge(7, 11)
    g.add_edge(7, 12)
    g.add_edge(8, 12)
    g.add_edge(8, 13)
    g.add_edge(9, 13)
    g.add_edge(9, 14)
    g.add_edge(10, 14)
    g.add_edge(10, 15)

def tree():

    with open("graph_radio.json", "w") as f:
        f.write(json_graph.dumps(g,sort_keys=True,
            indent=4, separators=(',', ': ') ))

        # Drawing
    pos = nx.spectral_layout(g)
    nx.draw(g, pos, node_color="g")
    nx.draw_networkx_nodes(g, pos, nodelist=[1], node_color="b")

    plt.savefig("topology_tree.pdf", format="pdf")
    plt.show()

def plot_graph_chain(folder):
    g = nx.DiGraph()

    N = 7

    for i in range(1, N):
        g.add_edge(i + 1, i)

    g.add_node(1, root=True)

    with open("radio_tree.json", "w") as f:
        f.write(json_graph.dumps(g, sort_keys=True,
                indent=4, separators=(',', ': ')))

    pos = nx.circular_layout(g)
    nx.draw(g, pos=pos)
    nx.draw_networkx_nodes(g, pos, node_color='g')
    nx.draw_networkx_nodes(g, pos, nodelist=[1], node_color='b')

    nx.draw_networkx_edges(g, pos, edge_color="r", arrows=True)

    plt.savefig(pj(folder, "topology_chain.pdf"), format="pdf")

def flower():

    g = wheel_graph(7)

    g.add_edge(6, 1)
    g.add_edge(7, 6)
    g.add_edge(8, 7)

    with open("radio_graph.json", "w") as f:
        f.write(json_graph.dumps(g, sort_keys=True,
                indent=4, separators=(',', ': ')))

    pos = nx.spring_layout(g)
    nx.draw(g, pos=pos)
    nx.draw_networkx_nodes(g,pos,
                           node_color='g')
    nx.draw_networkx_nodes(g,pos,
                           nodelist=[8],
                           node_color='b')

    #nx.draw_networkx_edges(g, pos, edge_color="r", arrows=True)

    plt.savefig("topology_fleur.pdf", format="pdf")
    plt.show()


def plot_graph(self):
    """
    Plot the transmission graph of the simulation.

    TODO: Draw arrows and have a directed graph.
    http://goo.gl/Z697dH

    TODO: Graph with big nodes for big transmissions
    """
    fig = plt.figure()
    ax1 = fig.add_subplot(111)
    ax1.set_title("Transmission / RPL tree")
    ax1.axis("off")

    val_color = {"udp_server": 0.5714285714285714}

    pos = {node: data["pos"]
           for node, data in self.radio_tree.nodes(data=True)}

    # color for all nodes
    node_color = [val_color.get(data["mote_type"], 0.25)
                  for node, data in self.radio_tree.nodes(data=True)]
    # Drawing the nodes
    nx.draw_networkx_nodes(self.radio_tree, pos, node_color=node_color, ax=ax1)
    nx.draw_networkx_labels(self.radio_tree, pos, ax=ax1)

    # Drawing radio edges
    nx.draw_networkx_edges(self.radio_tree, pos, edgelist=self.radio_tree.edges(),
                           width=8, alpha=0.5, ax=ax1)

    # Adding the depth of each node.
    with open(PJ(self.result_dir, "depth.csv")) as depth_f:
        reader = DictReader(depth_f)
        for row in reader:
            node = int(row["node"])
            depth = row["depth"]

            ax1.text(pos[node][0] + 5, pos[node][1] + 5, depth,
                     bbox=dict(facecolor='red', alpha=0.5),
                     horizontalalignment='center')

    # Drawing RPL edges
    nx.draw_networkx_edges(
        self.rpl_tree, pos, edge_color='r', nodelist=[], arrows=True, ax=ax1)

    img_path = PJ(self.img_dir, "graph.pdf")
    fig.savefig(img_path, format="pdf")
    update_report(self.result_dir, "plot_graph", {
        "img_src": "img/graph.pdf",
        "comment": """
        When the edge is thick it means edges are in an RPL instance.
        Otherwise it means that the two nodes can see each others.
        """,
        "text": """
        We generate a random geometric graph then use information coming
        to the RPL root to construct the gateway representation of the RPL
        tree. We add into this tree representation the traffic generated.
        """})

def transmission_graph(self):
    """
    Plot the transmission graph of the simulation.
    """
    settings = self.settings["transmission_graph"]
    output_path = pj(self.result_folder_path, *settings["output_path"])
    fig_rplinfo, ax_transmission_graph = plt.subplots()


    net = nx.Graph()

    # nodes
    mote_types = self.settings["mote_types"]
    motes = self.settings["motes"]
    position = {}
    for mote in motes:
        mote_type = mote["mote_type"]
        mote_id = mote["mote_id"]
        position[mote_id] = (mote["x"], mote["y"])
        mote_types[mote_type] \
            .setdefault("nodes", []) \
            .append(mote["mote_id"])

    # edges
    transmitting_range = self.settings["transmitting_range"]
    for couple in itertools.product(motes, motes):
        if 0 < distance(couple) <= transmitting_range:
            net.add_edge(couple[0]["mote_id"],
                         couple[1]["mote_id"])

    for mote_type in mote_types:
        color = mote_types[mote_type]["color"]
        nodelist = mote_types[mote_type]["nodes"]
        nx.draw_networkx_nodes(net, position,
                               nodelist=nodelist,
                               node_color=color,
                               ax=ax_transmission_graph)
    nx.draw_networkx_edges(net, pos=position, ax=ax_transmission_graph)

    # labels
    nx.draw_networkx_labels(net, position, ax=ax_transmission_graph)

    plt.axis('off')
    plt.savefig(output_path)  # save as PNG
    return ax_transmission_graph


def rpl_graph(folder):
    """
    Build up the RPL representation at the gateway
    """
    output_folder = pj(folder, "results", "graph")
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    df = pd.read_csv(pj(folder, "results", "messages.csv"))
    parent_df = df[df.message_type == "parent"]

    rpl_graph = nx.DiGraph()
    for c, p in parent_df.iterrows():
        rpl_graph.add_edge(p["mote_id"], p["node"])

    with open(pj(output_folder, "rpl_graph.json"), "w") as f:
        f.write(json.dumps(node_link_data(rpl_graph),
                sort_keys=True, indent=4))

[((14, 8, 14, 18), 'networkx.Graph', 'nx.Graph', ({}, {}), '()', True, 'import networkx as nx\n'), ((66, 10, 66, 31), 'networkx.spectral_layout', 'nx.spectral_layout', ({(66, 29, 66, 30): 'g'}, {}), '(g)', True, 'import networkx as nx\n'), ((67, 4, 67, 35), 'networkx.draw', 'nx.draw', (), '', True, 'import networkx as nx\n'), ((68, 4, 68, 64), 'networkx.draw_networkx_nodes', 'nx.draw_networkx_nodes', (), '', True, 'import networkx as nx\n'), ((74, 8, 74, 20), 'networkx.DiGraph', 'nx.DiGraph', ({}, {}), '()', True, 'import networkx as nx\n'), ((87, 10, 87, 31), 'networkx.circular_layout', 'nx.circular_layout', ({(87, 29, 87, 30): 'g'}, {}), '(g)', True, 'import networkx as nx\n'), ((88, 4, 88, 23), 'networkx.draw', 'nx.draw', (), '', True, 'import networkx as nx\n'), ((89, 4, 89, 50), 'networkx.draw_networkx_nodes', 'nx.draw_networkx_nodes', (), '', True, 'import networkx as nx\n'), ((90, 4, 90, 64), 'networkx.draw_networkx_nodes', 'nx.draw_networkx_nodes', (), '', True, 'import networkx as nx\n'), ((92, 4, 92, 63), 'networkx.draw_networkx_edges', 'nx.draw_networkx_edges', (), '', True, 'import networkx as nx\n'), ((108, 10, 108, 29), 'networkx.spring_layout', 'nx.spring_layout', ({(108, 27, 108, 28): 'g'}, {}), '(g)', True, 'import networkx as nx\n'), ((109, 4, 109, 23), 'networkx.draw', 'nx.draw', (), '', True, 'import networkx as nx\n'), ((110, 4, 111, 42), 'networkx.draw_networkx_nodes', 'nx.draw_networkx_nodes', (), '', True, 'import networkx as nx\n'), ((112, 4, 114, 42), 'networkx.draw_networkx_nodes', 'nx.draw_networkx_nodes', (), '', True, 'import networkx as nx\n'), ((145, 4, 145, 79), 'networkx.draw_networkx_nodes', 'nx.draw_networkx_nodes', (), '', True, 'import networkx as nx\n'), ((146, 4, 146, 57), 'networkx.draw_networkx_labels', 'nx.draw_networkx_labels', (), '', True, 'import networkx as nx\n'), ((164, 4, 165, 77), 'networkx.draw_networkx_edges', 'nx.draw_networkx_edges', (), '', True, 'import networkx as nx\n'), ((186, 18, 186, 71), 'os.path.join', 'pj', ({(186, 21, 186, 44): 'self.result_folder_path', (186, 46, 186, 70): "*settings['output_path']"}, {}), "(self.result_folder_path, *settings['output_path'])", True, 'from os.path import join as pj\n'), ((190, 10, 190, 20), 'networkx.Graph', 'nx.Graph', ({}, {}), '()', True, 'import networkx as nx\n'), ((218, 4, 218, 71), 'networkx.draw_networkx_edges', 'nx.draw_networkx_edges', (), '', True, 'import networkx as nx\n'), ((221, 4, 221, 68), 'networkx.draw_networkx_labels', 'nx.draw_networkx_labels', (), '', True, 'import networkx as nx\n'), ((232, 20, 232, 50), 'os.path.join', 'pj', ({(232, 23, 232, 29): 'folder', (232, 31, 232, 40): '"""results"""', (232, 42, 232, 49): '"""graph"""'}, {}), "(folder, 'results', 'graph')", True, 'from os.path import join as pj\n'), ((239, 16, 239, 28), 'networkx.DiGraph', 'nx.DiGraph', ({}, {}), '()', True, 'import networkx as nx\n'), ((94, 16, 94, 48), 'os.path.join', 'pj', ({(94, 19, 94, 25): 'folder', (94, 27, 94, 47): '"""topology_chain.pdf"""'}, {}), "(folder, 'topology_chain.pdf')", True, 'from os.path import join as pj\n'), ((214, 8, 217, 56), 'networkx.draw_networkx_nodes', 'nx.draw_networkx_nodes', (), '', True, 'import networkx as nx\n'), ((233, 11, 233, 40), 'os.path.exists', 'os.path.exists', ({(233, 26, 233, 39): 'output_folder'}, {}), '(output_folder)', False, 'import os\n'), ((234, 8, 234, 34), 'os.makedirs', 'os.makedirs', ({(234, 20, 234, 33): 'output_folder'}, {}), '(output_folder)', False, 'import os\n'), ((236, 21, 236, 58), 'os.path.join', 'pj', ({(236, 24, 236, 30): 'folder', (236, 32, 236, 41): '"""results"""', (236, 43, 236, 57): '"""messages.csv"""'}, {}), "(folder, 'results', 'messages.csv')", True, 'from os.path import join as pj\n'), ((243, 14, 243, 49), 'os.path.join', 'pj', ({(243, 17, 243, 30): 'output_folder', (243, 32, 243, 48): '"""rpl_graph.json"""'}, {}), "(output_folder, 'rpl_graph.json')", True, 'from os.path import join as pj\n'), ((244, 27, 244, 52), 'networkx.readwrite.json_graph.node_link_data', 'node_link_data', ({(244, 42, 244, 51): 'rpl_graph'}, {}), '(rpl_graph)', False, 'from networkx.readwrite.json_graph import node_link_data\n')]