'''
The functions for intentRerouteLat

'''
import numpy
import time
import json

def _init_( self ):
    self.default = ''

def sanityCheck( main, linkNumExpected, flowNumExpected, intentNumExpected ):
    '''
    Sanity check on numbers of links, flows and intents in ONOS
    '''
    attemps = 0
    main.verify = main.FALSE
    linkNum = 0
    flowNum = 0
    intentNum = 0
    while attemps <= main.verifyAttempts:
        time.sleep(main.verifySleep)
        summary = json.loads( main.Cluster.active( 0 ).CLI.summary( timeout=main.timeout ) )
        linkNum = summary.get("links")
        flowNum = summary.get("flows")
        intentNum = summary.get("intents")
        if linkNum == linkNumExpected and flowNum == flowNumExpected and intentNum == intentNumExpected:
            main.log.info("links: {}, flows: {}, intents: {}".format(linkNum, flowNum, intentNum))
            main.verify = main.TRUE
            break
        attemps += 1
    if not main.verify:
        main.log.warn("Links or flows or intents number not as expected")
        main.log.warn("links: {}, flows: {}, intents: {}".format(linkNum, flowNum, intentNum))
        # bring back topology
        bringBackTopology( main )
        if main.validRun >= main.warmUp:
            main.invalidRun += 1
        else:
            main.validRun += 1

def bringBackTopology( main ):
    main.log.info( "Bring back topology " )
    main.Cluster.active( 0 ).CLI.pushTestIntents( main.ingress,
                                                  main.egress,
                                                  main.batchSize,
                                                  offset=1,
                                                  options="-w",
                                                  timeout=main.timeout)
    main.Cluster.active( 0 ).CLI.purgeWithdrawnIntents()
    main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
                                         "deviceCount",
                                         value=0)
    main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
                                         "enabled",
                                         value="false")
    main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
                                         "deviceCount",
                                         value=main.deviceCount)
    main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
                                         "enabled",
                                         value="true")
    main.Cluster.active( 0 ).CLI.balanceMasters()
    time.sleep( main.setMasterSleep )
    if main.Cluster.numCtrls > 1:
        main.Cluster.active( 0 ).CLI.deviceRole( main.end1[ 'name' ],
                                                 main.Cluster.active( 0 ).ipAddress )
        main.Cluster.active( 0 ).CLI.deviceRole( main.end2[ 'name' ],
                                                 main.Cluster.active( 0 ).ipAddress )
    time.sleep( main.setMasterSleep )

def getLogNum( main, nodeId ):
    '''
    Return the number of karaf log files
    '''
    try:
        logNameList = main.ONOSbench.listLog( main.Cluster.active( nodeId ).ipAddress )
        assert logNameList is not None
        # FIXME: are two karaf logs enough to cover the events we want?
        if len( logNameList ) >= 2:
            return 2
        return 1
    except AssertionError:
        main.log.error("There is no karaf log")
        return -1

def getTopologyTimestamps( main ):
    '''
    Get timestamps for the last topology events on all cluster nodes
    '''
    timestamps = []
    for i in range( main.Cluster.numCtrls ):
        # Search for last topology event in karaf log
        lines = main.Cluster.active( i ).CLI.logSearch( mode='last',
                                                        searchTerm=main.searchTerm[ "TopologyTime" ],
                                                        startLine=main.startLine[ i ],
                                                        logNum=getLogNum( main, i ) )
        if lines is None or len( lines ) != 1:
            main.log.error( "Error when trying to get topology event timestamp" )
            return main.ERROR
        try:
            timestampField = lines[0].split( "creationTime=" )
            timestamp = timestampField[ 1 ].split( "," )
            timestamp = int( timestamp[ 0 ] )
            timestamps.append( timestamp )
        except KeyError:
            main.log.error( "Error when trying to get intent key or timestamp" )
            return main.ERROR
    return timestamps

def getIntentTimestamps( main ):
    '''
    Get timestamps for all intent keys on all cluster nodes
    '''
    timestamps = {}
    for i in range( main.Cluster.numCtrls ):
        # Search for intent INSTALLED event in karaf log
        lines = main.Cluster.active( i ).CLI.logSearch( mode='all',
                                                        searchTerm=main.searchTerm[ "InstallTime" ],
                                                        startLine=main.startLine[ i ],
                                                        logNum=getLogNum( main, i ) )
        if lines is None or len( lines ) == 0:
            main.log.error( "Error when trying to get intent key or timestamp" )
            return main.ERROR
        for line in lines:
            try:
                # Get intent key
                keyField = line.split( "key=" )
                key = keyField[ 1 ].split( "," )
                key = key[ 0 ]
                if not key in timestamps.keys():
                    timestamps[ key ] = []
                # Get timestamp
                timestampField = line.split( "time = " )
                timestamp = timestampField[ 1 ].split( " " )
                timestamp = int( timestamp[ 0 ] )
                timestamps[ key ].append( timestamp )
            except KeyError:
                main.log.error( "Error when trying to get intent key or timestamp" )
                return main.ERROR
    return timestamps

def calculateLatency( main, topologyTimestamps, intentTimestamps ):
    '''
    Calculate reroute latency values using timestamps
    '''
    topologyTimestamp = numpy.min( topologyTimestamps )
    firstInstalledLatency = {}
    lastInstalledLatency = {}
    for key in intentTimestamps.keys():
        firstInstalledTimestamp = numpy.min( intentTimestamps[ key ] )
        lastInstalledTimestamp = numpy.max( intentTimestamps[ key ] )
        firstInstalledLatency[ key ] = firstInstalledTimestamp - topologyTimestamp
        lastInstalledLatency[ key ] = lastInstalledTimestamp - topologyTimestamp
    firstLocalLatnecy = numpy.min( firstInstalledLatency.values() )
    lastLocalLatnecy = numpy.max( firstInstalledLatency.values() )
    firstGlobalLatency = numpy.min( lastInstalledLatency.values() )
    lastGlobalLatnecy = numpy.max( lastInstalledLatency.values() )
    main.log.info( "firstLocalLatnecy: {}, lastLocalLatnecy: {}, firstGlobalLatency: {}, lastGlobalLatnecy: {}".format( firstLocalLatnecy, lastLocalLatnecy, firstGlobalLatency, lastGlobalLatnecy ) )
    return firstLocalLatnecy, lastLocalLatnecy, firstGlobalLatency, lastGlobalLatnecy
