import subprocess
import time
import threading
import signal
import json
from read_config import read_config
from datetime import datetime


class myThread3 (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.flag=0

    def set(self):
        self.flag=1
        self.p.send_signal(signal.SIGINT)
    
    
    def run(self):
        '''
        This method runs the thread and nethogs commands for gathering data usage per app.
        This parses the ouput generated by the nethogs command, parses the information,
        stores the information in a json file. Through the json file, graph is generated for 
        better representation of data

        
        :returns: A json file with a graph depicting the data usage  
        '''
        t1 = time.time()
        ######### Running the nethogs command
        self.p = subprocess.Popen(['nethogs', '-v3', '-d1',"-t"],stdout=subprocess.PIPE,stderr=subprocess.STDOUT,universal_newlines=True)  
        

        local_time1 = time.ctime(t1) ####### Storing the start time

        
        out, err = self.p.communicate()####### storing the output of the nethogs command
        
        lines = out.split("\n")
        ############################################################################################################
        ########################## Making dictionary data out of the stored output ################################

        data = {}
        count=0
        for i in range(len(lines)):
            entries = lines[i].split("\t")
            try:
                
                Name = entries[0]
                
                if Name.split("/")[-1]=="0" or Name=="unknown":
                    
                    continue
                
                else:
                    x = Name.split("/")
                    if len(x[-3])<=25:
                        Name=x[-3]
                    else:
                        for k in range(len(x)):
                            if len(x[i]>25):
                                Name=x[i].split(" ")[0]
                                break
                                
                
                
                
                Upload = entries[1]
                Download=entries[2].split("\n")[0]
                
                if Name in data:
                    data[Name]["Upload"]= float(Upload)
                    data[Name]["Download"]= float(Download)
                else:
                    data[Name]={}
                    data[Name]["Upload"]= float(Upload)
                    data[Name]["Download"]= float(Download)
                
            except:
                continue

        for key in data.keys():
            data[key]["total"]=data[key]["Upload"]+data[key]["Download"]
        json_object = json.dumps(data, indent = 4) 
  
        ###############################################################################################################
        ############################# Writing Data in a json file ####################################################

        with open('../results/DataUsage/'+read_config()+'_'+datetime.now().strftime("%d-%m-%Y_%H:%M:%S")+'.json', "w") as outfile: 
            outfile.write(json_object) 
    
        #############################################################################################################
        ########################################## Plotting the graph for per app data usage#######################
        import matplotlib.pyplot as plt
        import operator 
        x= []
        y= []
        for key in data.keys():
            y.append(data[key]["total"])
            x.append(key)
        zipped = zip(x, y)
        zipped = list(zipped) 
        res = sorted(zipped, key = operator.itemgetter(1),reverse=True) 

        x_p = [res[i][0] for i in range(len(res))]
        y_p = [res[i][1] for i in range(len(res))]
        plt.bar(range(len(x_p)), y_p, align='center')
        plt.xticks(range(len(x_p)), x_p)
        plt.xlabel('Applications')
        plt.ylabel('Data usage in Mbs')
        t2 = time.time()
        local_time2 = time.ctime(t2)
        plt.title("From "+local_time1+" to "+local_time2)
        plt.savefig("../results/DataUsage/"+read_config()+"_"+datetime.now().strftime("%d-%m-%Y_%H:%M:%S")+"plt.png")

        ################################## saving the graph according to the course name and start time #######################
        
