__author__ = 'Jura'

import numpy as np
import csv
import math
import counting
import networkx as nx
import matplotlib.pyplot
import matplotlib.pyplot as plt



staticGraphlets = {
    0: [(1,2)],
    1: [(1,2),(2,3)],
    2: [(1,2),(2,3),(3,1)],
    3: [(1,2),(2,3),(3,4)],
    4: [(1,2),(2,3),(2,4)],
    5: [(1,2),(2,3),(3,4),(4,1)],
    6: [(1,2),(2,3),(3,1),(3,4)],
    7: [(1,2),(2,3),(3,4),(4,1),(4,2)],
    8: [(1,2),(2,3),(3,1),(1,4),(2,4),(3,4)],
    9: [(1,2),(2,3),(3,4),(4,5)],
    10: [(1,2),(2,3),(3,4),(3,5)],
    11: [(1,2),(2,3),(2,4),(2,5)],
    12: [(1,2),(2,3),(3,1),(2,4),(3,5)],
    13: [(1,2),(2,3),(3,1),(3,4),(4,5)],
    14: [(1,2),(2,3),(3,1),(3,4),(3,5)],
    15: [(1,2),(2,3),(3,4),(4,5),(5,1)],
    16: [(1,2),(2,3),(3,4),(4,1),(4,5)],
    17: [(1,2),(2,3),(3,4),(4,1),(4,2),(4,5)],
    18: [(1,2),(2,3),(3,1),(3,4),(4,5),(5,3)],
    19: [(1,2),(2,3),(3,4),(4,1),(4,2),(1,5)],
    20: [(1,2),(2,3),(3,4),(4,1),(4,5),(5,2)],
    21: [(1,2),(2,3),(3,4),(4,1),(4,5),(5,3)],
    22: [(1,2),(2,3),(3,4),(4,1),(4,2),(2,5),(4,5)],
    23: [(1,2),(2,3),(3,1),(1,4),(2,4),(3,4),(1,5)],
    24: [(1,2),(2,3),(3,1),(2,4),(3,4),(3,5),(4,5)],
    25: [(1,2),(2,3),(3,4),(4,1),(4,5),(5,2),(5,1)],
    26: [(1,2),(2,3),(3,4),(4,1),(4,2),(2,5),(4,5),(5,1)],
    27: [(1,2),(2,3),(3,4),(4,1),(1,5),(2,5),(3,5),(4,5)],
    28: [(1,2),(2,3),(3,4),(4,1),(4,2),(2,5),(4,5),(5,1),(1,3)],
    29: [(1,2),(1,3),(1,4),(1,5),(2,3),(2,4),(2,5),(3,4),(3,5),(4,5)]
}


def generate_temporal_graphlets(kMax, nMax = None):
    print 'Generating all temporal graphlets with up to %s nodes and %s events' % (nMax, kMax)

    temporalGraphlets = {
        1: [[1,2]]
    }
    i=1

    for k in range(2,kMax+1):

        temporalGraphlets[k] = []
        for g in temporalGraphlets[k-1]:
            s = g[-2]
            t = g[-1]
            u = max(g)+1

            nodes = set(g)
            if len(nodes)==2:
                temporalGraphlets[k].append(g + [s,t])
                if nMax is None or nMax > 2:
                    temporalGraphlets[k].append(g + [t,u])
            else:
                for v in nodes:
                    if v==s:
                       temporalGraphlets[k].append(g + [s,t])
                    elif v!=t:
                       temporalGraphlets[k].append(g + sorted([s,v]))
                       temporalGraphlets[k].append(g + sorted([t,v]))
                if nMax is None or nMax > max(g):
                    temporalGraphlets[k].append(g + [s,u])
                    temporalGraphlets[k].append(g + [t,u])
        print '\t%s temporal graphlet(s) with %s events' % (len(temporalGraphlets[k]),k)
    return temporalGraphlets

def get_backbone(g):
    event_list = []
    for i in range(0,len(g),2):
        event_list.append((g[i],g[i+1]))

    return nx.from_edgelist(event_list)

def classify_temporal_graphlets_backbones(kMax):
    kCounts = dict.fromkeys(range(1,kMax+1),None)# for each number of events, counts for each static graphlet
    temporalGraphlets = generate_temporal_graphlets(kMax)

    print 'Classifying backbones of temporal graphlets with up to %s events' % kMax

    staticGraphletsGraphs = dict()
    maxStaticGraphletN = 0
    for s in staticGraphlets:
        staticGraphletsGraphs[s] = nx.from_edgelist(staticGraphlets[s])
        maxStaticGraphletN = max(maxStaticGraphletN,staticGraphletsGraphs[s].order())

    for k in temporalGraphlets.keys():
        kCounts[k] = dict.fromkeys(staticGraphlets.keys(), 0)
        print '\t%s events (%s temporal graphlets)' % (k,len(temporalGraphlets[k]))
        for tG in temporalGraphlets[k]:
            n = len(set(tG))

            if (n>maxStaticGraphletN):
                continue

            tGraph = get_backbone(tG)
            for s in staticGraphletsGraphs:
                sGraph = staticGraphletsGraphs[s]
                if sGraph.order()>n or sGraph.size()>k:
                    continue
                if nx.is_isomorphic(tGraph,sGraph):
                    kCounts[k][s] += 1
                    break
    return kCounts

# kCounts = classify_temporal_graphlets_backbones(10)
# with open("Backbone_counts.csv", 'wb') as csvfile:
#     writer = csv.writer(csvfile, dialect='excel')
#     kValues = sorted(kCounts.keys())
#     writer.writerow(['Graphlets'] + kValues)
#     for s in staticGraphlets:
#         counts = []
#         for k in kValues:
#             counts.append(kCounts[k][s])
#         writer.writerow(["G_%s" %s] +  counts)


def encode_graphlet(nodeSequence):
    encoding = ''
    nodeCodes = dict()
    nodeWith1 = None
    nodeWith2 = None
    cMax = 1
    i=0
    while i<len(nodeSequence):
        u = nodeSequence[i]
        v = nodeSequence[i+1]
        updated = False
        if not nodeCodes.has_key(u):
            nodeCodes[u] = cMax
            if cMax == 1:
                nodeWith1 = u
            if cMax == 2:
                nodeWith2 = u
            cMax += 1
            updated = True
        if not nodeCodes.has_key(v):
            nodeCodes[v] = cMax
            if cMax == 1:
                nodeWith1 = v
            if cMax == 2:
                nodeWith2 = v
            cMax += 1
            updated = True
        if cMax == 4 and updated:
            if (nodeCodes[u]==1 and nodeCodes[v]==3) or (nodeCodes[u]==3 and nodeCodes[v]==3):
                nodeCodes[nodeWith1] = 2
                nodeCodes[nodeWith2] = 1

        encoding += '%s%s' % (min(nodeCodes[u],nodeCodes[v]),max(nodeCodes[u],nodeCodes[v]))
        i+=2
    return encoding








def get_node_orbit_dependency_count(nodeOrbit):
    [g,v] = nodeOrbit.split('_')
    encounteredGraphlets = [g]
    o = 1 #count itself

    i=0
    while i<len(g):
        j=len(g)
        while j>i and v in g[i:j]:
            encoding = encode_graphlet(list(g[i:j]))
            if not encoding in encounteredGraphlets:
                encounteredGraphlets.append(encoding)
                print(encoding)
                o+=1
            j-=2
        i+=2


    return o

print get_node_orbit_dependency_count('12233445566778_8')

# for s in staticGraphlets:
#     G = nx.from_edgelist(staticGraphlets[s])
#     plt.clf()
#     nx.draw(G)
#     plt.savefig("images/static_graphlets/graphlet_%s" % s)

# graphlets = generate_temporal_graphlets(6)
# for k in range(1,len(graphlets.keys())+1):
#     print len(graphlets[k])





# print counting.dFormula(5,5)
# counting.fillRecursive(20,20)
# counting.fillFormula(20,20)

