'''
Created on Apr 24, 2011
Modified on  Apr 15, 2012
@author: Dilum Bandara
@version: 0.2
@license: Apache License v2.0

   Copyright 2012 H. M. N. Dilum Bandara and Anura P. Jayasumana, Colorado State
   University

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
'''

import PeerManager as PM

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

    def __init__(self, fileName, trackAttCost):
        '''
        Constructor
        @param fileName: File name to save stat
        @param trackAttCost: Are we suppose to track which attribute 
        contribute to cost  
        '''
        self._fdOut = open(fileName, 'w')
        self._trackAttCost = trackAttCost
        self._results = []


    def __del__(self):
        '''
        Destructor
        '''
        self._fdOut.close()


    def trackStat(self, eventType, value):
        '''
        Track statistics.
        @param eventType: Event type
        @param value: Statistics
        '''
        self._results.append([eventType, PM.EVENTS.now, value])


    def summStat(self):
        '''
        Dump stat to file
        '''
        for i in range(len(self._results)):
            if self._results[i][0] == 'Adv': 
                tmpStr = 'Adv\t' + str(self._results[i][1])
                for j in self._results[i][2][0]: tmpStr += '\t' + str(j)
                #If we need to track which attributes contribute to cost
                attStr = ''
                if self._trackAttCost == True:#How many attributes?
                    attStr = '\t' + str(len(self._results[i][2][2])) #How many?
                    for j in self._results[i][2][2]: attStr += '\t' + j #attribs
                    tmpStr += attStr
                self._fdOut.write(tmpStr + '\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): 
                    tmpStr = 'Rem\t' + str(self._results[i][1])
                    for j in self._results[i][2][1]: tmpStr += '\t' + str(j)
                    if self._trackAttCost == True: tmpStr += attStr
                    self._fdOut.write(tmpStr + '\n')                   
            elif self._results[i][0] == 'Que':
                tmpStr = 'Que\t' + str(self._results[i][1])
                #If we need to track which attributes contribute to cost
                for j in self._results[i][2][0]: tmpStr += '\t' + str(j)
                if self._results[i][2][1] == True: tmpStr += '\tT' #Success
                else: tmpStr += '\tF' #Query failed
                if self._trackAttCost == True:
                    attStr = '\t' + str(len(self._results[i][2][2])) #How many?
                    for j in self._results[i][2][2]: attStr += '\t' + j #attribs
                    tmpStr += attStr
                self._fdOut.write(tmpStr + '\n')
            elif (self._results[i][0] == 'DHT') or \
                    (self._results[i][0] == 'RemDHT') or \
                    (self._results[i][0] == 'Ovlay') or \
                    (self._results[i][0] == 'RemOvlay') or \
                    (self._results[i][0] == 'Res'):
                tmpStr = self._results[i][0] + '\t' + str(self._results[i][1])
                for j in self._results[i][2]: tmpStr += '\t' + str(j)
                self._fdOut.write(tmpStr + '\n')
            elif (self._results[i][0] == 'AddN') or \
                (self._results[i][0] == 'RemN'):
                tmpStr = self._results[i][0] + '\t' + str(self._results[i][1]) \
                    + '\t' + str(self._results[i][2][0]) + '\t' + \
                    str(self._results[i][2][1]) 
                self._fdOut.write(tmpStr + '\n')
            elif self._results[i][0] == 'Clust':
                tmpStr = 'Clust\t' + str(self._results[i][1]) + '\t' + \
                    str(self._results[i][2][0])
                for j in range(len(self._results[i][2]) - 1):
                    tmpStr += '\t' + str(self._results[i][2][j + 1])
                self._fdOut.write(tmpStr + '\n')    
            elif self._results[i][0] == 'LdChk':
                tmpStr = 'LdChk\t' + str(self._results[i][1]) + '\t' + \
                    str(self._results[i][2])
                self._fdOut.write(tmpStr + '\n')
            elif self._results[i][0] == 'NodeKey': #No of nodes
                tmpStr = self._results[i][0] + '\t' + str(self._results[i][1])\
                    + '\t' + str(len(self._results[i][2]))
                for j in self._results[i][2]: tmpStr += '\t' + str(j)
                self._fdOut.write(tmpStr + '\n')
            elif (self._results[i][0] == 'AddFrag') or \
                    (self._results[i][0] == 'AddRep') or \
                    (self._results[i][0] == 'AddSuce') or \
                    (self._results[i][0] == 'AddPred') or \
                    (self._results[i][0] == 'Leave') or \
                    (self._results[i][0] == 'TranSuce') or \
                    (self._results[i][0] == 'TranPred'):
                tmpStr = self._results[i][0] + '\t' + str(self._results[i][1])
                for j in self._results[i][2]: tmpStr += '\t' + str(j)
                self._fdOut.write(tmpStr + '\n')
            elif (self._results[i][0] == 'NIDs'):
                tmpStr = self._results[i][0] + '\t' + str(self._results[i][1])\
                     + '\t' + str(self._results[i][2][0]) + '\t' + \
                     str(self._results[i][2][1])
                self._fdOut.write(tmpStr + '\n')
            else: assert(False), 'Unknown stat attribute ' + self._results[i][0]   
        self._results = []