# -*- coding: utf-8 -*-
# !/usr/bin/python
################################### PART0 DESCRIPTION #################################
# Filename: class_compute_meta_data_of_network.py
# Description:
#


# Author: Shuai Yuan
# E-mail: ysh329@sina.com
# Create: 2015-12-06 21:49:46
# Last:
__author__ = 'yuens'

################################### PART1 IMPORT ######################################
import logging
import MySQLdb
import time
from operator import add
import networkx as nx
from Tkinter import _flatten
################################### PART2 CLASS && FUNCTION ###########################
class ComputeEdgeProperty(object):
    def __init__(self, database_name, pyspark_sc):
        self.start = time.clock()

        logging.basicConfig(level = logging.INFO,
                  format = '%(asctime)s  %(levelname)5s %(filename)19s[line:%(lineno)3d] %(funcName)s %(message)s',
                  datefmt = '%y-%m-%d %H:%M:%S',
                  filename = './main.log',
                  filemode = 'a')
        console = logging.StreamHandler()
        console.setLevel(logging.INFO)

        formatter = logging.Formatter('%(asctime)s  %(levelname)5s %(filename)19s[line:%(lineno)3d] %(funcName)s %(message)s')
        console.setFormatter(formatter)

        logging.getLogger('').addHandler(console)
        logging.info("START CLASS {class_name}.".format(class_name = ComputeEdgeProperty.__name__))

        # connect database
        try:
            self.con = MySQLdb.connect(host='localhost', user='root', passwd='931209', db = database_name, charset='utf8')
            logging.info("Success in connecting MySQL.")
        except MySQLdb.Error, e:
            logging.error("Fail in connecting MySQL.")
            logging.error("MySQL Error {error_num}: {error_info}.".format(error_num = e.args[0], error_info = e.args[1]))

        # spark configure
        try:
            self.sc = pyspark_sc
            logging.info("Config spark successfully.")
        except Exception as e:
            logging.error("Config spark failed.")
            logging.error(e)



    def __del__(self):
        # close database
        try:
            self.con.close()
            logging.info("Success in quiting MySQL.")
        except MySQLdb.Error, e:
            logging.error("MySQL Error {error_num}: {error_info}.".format(error_num = e.args[0], error_info = e.args[1]))

        logging.info("END CLASS {class_name}.".format(class_name = ComputeEdgeProperty.__name__))
        self.end = time.clock()
        logging.info("The class {class_name} run time is : {delta_time} seconds".format(class_name = ComputeEdgeProperty.__name__, delta_time = self.end))



    def compute_common_degree_in_different_network(self, database_name, node_table_name, connection_table_name):
        # sub-function
        def get_node_and_connection_data_from_database(self, database_name, node_table_name, connection_table_name):
            cursor = self.con.cursor()
            sqls = ["SELECT network_type, is_directed, node,"
                    " degree_str, in_degree_str, out_degree_str"
                    " FROM {database}.{table}"\
                    .format(database = database_name,\
                           table = node_table_name)]

            sqls.append("SELECT network_type, is_directed, node1, node2"
                        " FROM {database}.{table}"\
                        .format(database = database_name,\
                                table = connection_table_name))
            for sql_idx in xrange(len(sqls)):
                sql = sqls[sql_idx]
                try:
                    cursor.execute(sql)
                    if sql_idx == 0:
                        node_tuple_list = map(lambda (network_type,\
                                                         is_directed,\
                                                         node,\
                                                         degree_str,\
                                                         in_degree_str,\
                                                         out_degree_str): (str(network_type),\
                                                                           int(is_directed),\
                                                                           int(node),\
                                                                           str(degree_str),\
                                                                           str(in_degree_str),\
                                                                           str(out_degree_str)),\
                                              cursor.fetchall()\
                                              )
                        logging.info("len(node_tuple_list):{0}".format(len(node_tuple_list)))
                        logging.info("node_tuple_list[:3]:{0}".format(node_tuple_list[:3]))
                    elif sql_idx == 1:
                        connection_tuple_list = map(lambda (network_type,\
                                                               is_directed,\
                                                               node1,\
                                                               node2): (str(network_type),\
                                                                        int(is_directed),\
                                                                        int(node1),\
                                                                        int(node2)\
                                                                        ),\
                                                    cursor.fetchall()\
                                                    )
                        logging.info("len(connection_tuple_list):{0}".format(len(connection_tuple_list)))
                        logging.info("connection_tuple_list[:3]:{0}".format(connection_tuple_list[:3]))
                except MySQLdb.Error, e:
                    logging.error("failed to get node and connection data from database.")
                    logging.error("MySQL Error {error_num}: {error_info}.".format(error_num = e.args[0], error_info = e.args[1]))
            cursor.close()
            return node_tuple_list, connection_tuple_list

        # sub-function
        def compute_common_degree_in_network(network_type, is_directed, node_tuple_list, connection_tuple_list):
            node_tuple_list = filter(lambda (network_type_,\
                                                is_directed_,\
                                                node,\
                                                degree_str,\
                                                in_degree_str,\
                                                out_degree_str): network_type_ == network_type and is_directed_ == is_directed,\
                                     node_tuple_list\
                                     )
            edge_tuple_list = filter(lambda (network_type_,\