# make the other metrics work
# generate the txt files, then work on the pdf otuput
__version__ = "0.1.0"
import numpy as np
import pandas as pd
# import matplotlib
# matplotlib.use('pdf')
import matplotlib.pyplot as plt
import sys
import os
import networkx as nx
import PHRG
import probabilistic_cfg as pcfg
import net_metrics as metrics
import re # import pprint as pp
import argparse, traceback

DBG = False

def get_parser ():
  parser = argparse.ArgumentParser(description='exact_phrg: infer a model given a graph (derive a model')
  parser.add_argument('g_fname', metavar='G_FNAME', nargs=1, help='Filename of edgelist graph')
  parser.add_argument('--chunglu',  help='Generate chunglu graphs',action='store_true')
  parser.add_argument('--kron',  help='Generate Kronecker product graphs',action='store_true')
  parser.add_argument('--version', action='version', version=__version__)
  return parser

def Hstar_Graphs_Control (G, graph_name, axs):
  print '-',Hstar_Graphs_Control,'-'
  # Derive the prod rules in a naive way, where
  prod_rules = PHRG.probabilistic_hrg_learning(G)
  print prod_rules
  g = pcfg.Grammar('S')
  for (id, lhs, rhs, prob) in prod_rules:
    g.add_rule(pcfg.Rule(id, lhs, rhs, prob))

  num_nodes = G.number_of_nodes()

  print "Starting max size", 'n=', num_nodes
  g.set_max_size(num_nodes)

  print "Done with max size"

  Hstars = []

  num_samples = 20
  print '*' * 40
  for i in range(0, num_samples):
    rule_list = g.sample(num_nodes)
    hstar = PHRG.grow(rule_list, g)[0]
    Hstars.append(hstar)

  # if 0:
  #   g = nx.from_pandas_dataframe(df, 'src', 'trg', edge_attr=['ts'])
  #   draw_degree_whole_graph(g,axs)
  #   draw_degree(Hstars, axs=axs, col='r')
  #   #axs.set_title('Rules derived by ignoring time')
  #   axs.set_ylabel('Frequency')
  #   axs.set_xlabel('degree')

  if 1:
    # metricx = [ 'degree','hops', 'clust', 'assort', 'kcore','eigen','gcd']
    metricx = ['degree', 'gcd']
    # g = nx.from_pandas_dataframe(df, 'src', 'trg',edge_attr=['ts'])
    # graph_name = os.path.basename(f_path).rstrip('.tel')
    if DBG: print ">", graph_name
    metrics.network_properties([G], metricx, Hstars, name=graph_name, out_tsv=True)


def pandas_dataframes_from_edgelists (el_files):
  if (el_files is None):  return
  list_of_dataframes = []
  for f in el_files:
    print '~' * 80
    print f
    temporal_graph = False
    with open(f, 'r') as ifile:
      line = ifile.readline()
      while (not temporal_graph):
        if ("%" in line):
          line = ifile.readline()
        elif len(line.split()) > 3:
          temporal_graph = True
    if (temporal_graph):
      dat = np.genfromtxt(f, dtype=np.int64, comments='%', delimiter="\t", usecols=[0, 1, 3], autostrip=True)
      df = pd.DataFrame(dat, columns=['src', 'trg', 'ts'])
    else:
      dat = np.genfromtxt(f, dtype=np.int64, comments='%', delimiter="\t", usecols=[0, 1], autostrip=True)
      df = pd.DataFrame(dat, columns=['src', 'trg'])
    df = df.drop_duplicates()
    list_of_dataframes.append(df)

  return list_of_dataframes

def grow_exact_size_hrg_graphs_from_prod_rules(prod_rules, gname, n, runs=1):
  """
  Args:
    rules: production rules (model)
    gname: graph name
    n:     target graph order (number of nodes)
    runs:  how many graphs to generate
  Returns: list of synthetic graphs

  """
  if n <=0: sys.exit(1)

  # print runs
  # for i,x in enumerate(prod_rules):
  #   print i,'  ', x
  
  g = pcfg.Grammar('S')
  for (id, lhs, rhs, prob) in prod_rules:
    rhs = [f[1:-1] for f in re.findall("'.+?'", rhs)]
    prob = float(prob)
    g.add_rule(pcfg.Rule(id, lhs, rhs, prob))

  # # mask = (pddf['ts'] >= pddf['ts'].min()+ span*kSlice) & (pddf['ts'] < pddf['ts'].min()+ span*(kSlice +1))
  # mask = (pddf['ts'] >= pddf['ts'].min()) & (pddf['ts'] < pddf['ts'].min() + span * (kSlice + 1))
  # ldf = pddf.loc[mask]
  #
  # G = nx.from_pandas_dataframe(ldf, 'src', 'trg', ['ts'])
  #
  num_nodes = n
  if DBG: print "Starting max size"
  g.set_max_size(num_nodes)
  if DBG: print "Done with max size"