'''
Created on Apr 24, 2011
Modified on  June 28, 2011
@author: Dilum Bandara
@version: 0.12
@copyright: Copyright(c) 2011, Dilum Bandara
@license: GPL
Correct error where Rem messages are not counted
'''

import BaseConfig

class BaseStat(object):
    '''
    Statistics class. Track stat & save them on file
    '''

    def __init__(self, file_name, track_att_cost):
        '''
        Constructor
        @param file_name: File name to save stat
        @param track_att_cost: Are we suppose to track which attribute contribute to cost  
        '''
        self._fdOut = open(file_name, 'w')
        self._results = []
        self._track_att_cost = track_att_cost
    
    
    def track_stat(self, type, time, value):
        '''
        Track statistics. Dump to file once in a while to preserve memory
        @param type: Event type
        @param time: Event time
        @param value: Statistics
        '''
        self._results.append([type, time, value])
        if len(self._results) > BaseConfig.DUMP_RESULTS_SIZE: #Time to dump these to file
            for i in range(len(self._results)):
                if self._results[i][0] == 'adv': 
                    tmp_str = 'Adv\t' + str(self._results[i][1])
                    #If we need to track which attributes contribute to cost
                    att_str = ''
                    if self._track_att_cost == True:
                        att_str = '\t' + str(len(self._results[i][2][2])) #How many attributes
                        for j in range(len(self._results[i][2][2])): #Which attributes
                            att_str += '\t' + self._results[i][2][2][j]              
                        tmp_str += att_str
                    for j in range(len(self._results[i][2][0])):
                        tmp_str += '\t' + str(self._results[i][2][0][j])
                    self._fdOut.write(tmp_str + '\n')
                    # if remove cost dump that as well
                    if len(self._results[i][2][1]) > 1 or (len(self._results[i][2][1]) == 1 \
                                                           and self._results[i][2][1][0] > 0): 
                        tmp_str = 'Rem\t' + str(self._results[i][1])
                        if self._track_att_cost == True: tmp_str += att_str                        
                        for j in range(len(self._results[i][2][1])):
                            tmp_str += '\t' + str(self._results[i][2][1][j])
                        self._fdOut.write(tmp_str + '\n')
                elif self._results[i][0] == 'DHTadv': 
                    tmp_str = 'DHTAdv\t' + str(self._results[i][1])
                    #If we need to track which attributes contribute to cost
                    att_str = ''
                    if self._track_att_cost == True:
                        att_str = '\t' + str(len(self._results[i][2][2])) #How many attributes
                        for j in range(len(self._results[i][2][2])): #Which attributes
                            att_str += '\t' + self._results[i][2][2][j]              
                        tmp_str += att_str
                    for j in range(len(self._results[i][2][0])):
                        tmp_str += '\t' + str(self._results[i][2][0][j])
                    self._fdOut.write(tmp_str + '\n')
                    # if remove cost dump that as well
                    if len(self._results[i][2][1]) > 1 or (len(self._results[i][2][1]) == 1 \
                                                            and self._results[i][2][1][0] > 0): 
                        tmp_str = 'DHTRem\t' + str(self._results[i][1])
                        if self._track_att_cost == True: tmp_str += att_str                        
                        for j in range(len(self._results[i][2][1])):
                            tmp_str += '\t' + str(self._results[i][2][1][j])
                        self._fdOut.write(tmp_str + '\n')        
                elif self._results[i][0] == 'que':
                    tmp_str = 'Que\t' + str(self._results[i][1])
                    #If we need to track which attributes contribute to cost
                    att_str = ''
                    if self._track_att_cost == True:
                        att_str = '\t' + str(len(self._results[i][2][2])) #How many attributes
                        for j in range(len(self._results[i][2][2])): #Which attributes
                            att_str += '\t' + self._results[i][2][2][j]
                        tmp_str += att_str                    
                    for j in range(len(self._results[i][2][0])):
                        tmp_str += '\t' + str(self._results[i][2][0][j])
                    if self._results[i][2][1] == True: tmp_str += '\t1'
                    else: tmp_str += '\t0'
                    self._fdOut.write(tmp_str + '\n')
                else: print 'Unknown stat attribute %s' % self._results[i][0]                
            print time
            self._results = [] #Reset stat collection

    
    def summ_stat(self):
        '''
        Dump any remaining adv/qyery stats & peer stat to file & summarize
        '''
        for i in range(len(self._results)):
            if self._results[i][0] == 'adv': 
                tmp_str = 'Adv\t' + str(self._results[i][1])
                #If we need to track which attributes contribute to cost
                att_str = ''
                if self._track_att_cost == True:
                    att_str = '\t' + str(len(self._results[i][2][2])) #How many attributes
                    for j in range(len(self._results[i][2][2])): #Which attributes
                        att_str += '\t' + self._results[i][2][2][j]
                    tmp_str += att_str
                for j in range(len(self._results[i][2][0])):
                    tmp_str += '\t' + str(self._results[i][2][0][j])
                self._fdOut.write(tmp_str + '\n')
                # if remove cost dump that as well
                if len(self._results[i][2][1]) > 1 or (len(self._results[i][2][1]) == 1 \
                                                        and self._results[i][2][1][0] > 0): 
                    tmp_str = 'Rem\t' + str(self._results[i][1])
                    if self._track_att_cost == True: tmp_str += att_str                        
                    for j in range(len(self._results[i][2][1])):
                        tmp_str += '\t' + str(self._results[i][2][1][j])
                    self._fdOut.write(tmp_str + '\n')
            elif self._results[i][0] == 'DHTadv': 
                tmp_str = 'DHTAdv\t' + str(self._results[i][1])
                #If we need to track which attributes contribute to cost
                att_str = ''
                if self._track_att_cost == True:
                    att_str = '\t' + str(len(self._results[i][2][2])) #How many attributes
                    for j in range(len(self._results[i][2][2])): #Which attributes
                        att_str += '\t' + self._results[i][2][2][j]
                    tmp_str += att_str
                for j in range(len(self._results[i][2][0])):
                    tmp_str += '\t' + str(self._results[i][2][0][j])
                self._fdOut.write(tmp_str + '\n')
                # if remove cost dump that as well
                if len(self._results[i][2][1]) > 1 or (len(self._results[i][2][1]) == 1 \
                     and self._results[i][2][1][0] > 0): 
                    tmp_str = 'DHTRem\t' + str(self._results[i][1])
                    if self._track_att_cost == True: tmp_str += att_str                        
                    for j in range(len(self._results[i][2][1])):
                        tmp_str += '\t' + str(self._results[i][2][1][j])
                    self._fdOut.write(tmp_str + '\n')        
            elif self._results[i][0] == 'que':
                tmp_str = 'Que\t' + str(self._results[i][1])
                #If we need to track which attributes contribute to cost
                if self._track_att_cost == True:
                    att_str = ''                    
                    att_str = '\t' + str(len(self._results[i][2][2])) #How many attributes
                    for j in range(len(self._results[i][2][2])): #Which attributes
                        att_str += '\t' + self._results[i][2][2][j]
                    tmp_str += att_str                    
                for j in range(len(self._results[i][2][0])):
                    tmp_str += '\t' + str(self._results[i][2][0][j])
                if self._results[i][2][1] == True: tmp_str += '\t1'
                else: tmp_str += '\t0'
                self._fdOut.write(tmp_str + '\n')
            else: print 'Unknown stat attribute %s' % self._results[i][0]            
        self._results = []
        #Dump statistics
        for i in BaseConfig.PEERS:
            stat = BaseConfig.PEERS[i].get_stat()
            if len(stat) == 7: tmp_str = 'PStat' #For peers
            else: tmp_str = 'SPStat' #Superpeer
            for j in range(0, len(stat)): tmp_str = tmp_str + '\t' + str(stat[j])
            self._fdOut.write(tmp_str + '\n')
        for i in BaseConfig.MANAGERS:
            tmp_str = 'CStat'
            stat = BaseConfig.MANAGERS[i].get_stat()
            for j in range(0, len(stat)): tmp_str = tmp_str + '\t' + str(stat[j])
            self._fdOut.write(tmp_str + '\n')    