'''
Created on Nov 9, 2011
@version: 0.1
@author: Dilum Bandara
@email: dilumb@engr.colostate.edu
@copyright: Copyright(c) 2011, Dilum Bandara
@license: GPL
'''

import Config as Config
import Distance as Distance
import PeerManager as PM

class NIC(object):
    '''
    Network Interface Card Class. Simulate the underlay
    Add & take events from discreete event engine
    '''


    def __init__(self, NID, loc, appType):
        '''
        Constructor
        @param NID: Node ID
        @param loc: Location of node
        @param appType: Application layer type. Used to track stat  
        '''
        self.NID = NID
        self.loc = loc
        self.type = appType
        self._nextPacketTime = 0.0 #Time next message can be issued
        self.dataRec = 0
        self.dataFwd = 0


    def fwdMsg(self, msg, destNID):
        '''
        Forward message directly to given node.
        @param msg: Message 
        @param destNID: Node ID of destination node
        @return : success or failure  
        '''
        if destNID in PM.UNDERLAY:            
            PM.UNDERLAY[destNID].recMsg(msg, self.NID, self.loc)
            self.dataFwd += msg.size 
            return True
        else: return False


    def recMsg(self, msg, sourceNID, sourceLoc):
        '''
        Forward message directly to given node. 
        Consider packet service & arrival time
        @param msg: Message 
        @param sourceNID: Node ID of destination node
        @param sourceLoc: Location of destination node
        '''
        self.dataRec += msg.size
        #propagation delay
        latency = Distance.dist(self.loc, sourceLoc)/Config.SPEED_LIGHT
        #Delay due to limited bandwidth. Convert to bits
        latency += msg.size/Config.BANDWIDTH
        fwdTime = -1.0
        currentTime = PM.EVENTS.now
        if currentTime > self._nextPacketTime: fwdTime = currentTime + latency
        else: fwdTime = self._nextPacketTime + latency
        self._nextPacketTime = fwdTime #Reset when next message can be received
        PM.EVENTS.addEvent(fwdTime, 'UnToOv', self.NID, \
                                [msg, sourceNID], True)
        

    def getStat(self):
        '''
        Get statistics
        @return: results
        '''
        return [self.dataRec, self.dataFwd]