class SCPFbatchFlowResp:
    '''
    Testing end-to-end ONOS response time from POST of batched flows to when ONOS returns
    response confirmation of all flows ADDED; subsequently testing the response time from when REST DELETE to
    ONOS confirmation of all flows REMOVED.
    '''

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

    def CASE1( self, main ):
        import time
        import os
        import imp

        """
        - Construct tests variables
        - GIT ( optional )
            - Checkout ONOS master branch
            - Pull latest ONOS code
        - Building ONOS ( optional )
            - Install ONOS package
            - Build ONOS package
        """

        main.case( "Constructing test variables and building ONOS package" )
        main.step( "Constructing test variables" )

        # Test variables
        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
        main.cellName = main.params[ 'CASE1' ][ 'cellName' ]
        main.apps = main.params[ 'CASE1' ][ 'cellApps' ]
        gitBranch = main.params[ 'CASE1' ][ 'gitBranch' ]
        gitPull = main.params[ 'CASE1' ][ 'gitPull' ]
        main.maxNodes = int( main.params['GLOBAL'][ 'maxNodes' ] )
        main.startUpSleep = float( main.params['GLOBAL'][ 'SLEEP' ][ 'startup' ] )
        main.startMNSleep = float( main.params['GLOBAL'][ 'SLEEP' ][ 'startMN' ] )
        main.addFlowSleep = float( main.params['GLOBAL'][ 'SLEEP' ][ 'addFlow' ] )
        main.delFlowSleep = float( main.params['GLOBAL'][ 'SLEEP' ][ 'delFlow' ] )
        main.chkFlowSleep = float( main.params['GLOBAL']['SLEEP']['chkFlow'])
        main.cfgSleep = float( main.params['GLOBAL']['SLEEP']['cfg'])
        main.numSw = int( main.params['GLOBAL']['numSw'])
        main.numThreads = int( main.params['GLOBAL']['numThreads'] )
        main.cellData = {} # for creating cell file
        main.CLIs = []
        main.ONOSip = []
        main.ONOSip = main.ONOSbench.getOnosIps()
        main.commit = main.ONOSbench.getVersion()
        main.cluster = main.params['GLOBAL']['cluster']

        # Assigning ONOS cli handles to a list
        for i in range( 1,  main.maxNodes + 1 ):
            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )


        if main.CLIs:
            stepResult = main.TRUE
        else:
            main.log.error( "Did not properly created list of ONOS CLI handle" )
            stepResult = main.FALSE

        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully construct " +
                                        "test variables ",
                                 onfail="Failed to construct test variables" )

        if gitPull == 'True':
            main.step( "Building ONOS in " + gitBranch + " branch" )
            onosBuildResult = main.startUp.onosBuild( main, gitBranch )
            stepResult = onosBuildResult
            utilities.assert_equals( expect=main.TRUE,
                                     actual=stepResult,
                                     onpass="Successfully compiled " +
                                            "latest ONOS",
                                     onfail="Failed to compile " +
                                            "latest ONOS" )
        else:
            main.log.warn( "Did not pull new code so skipping mvn " +
                           "clean install" )

    def CASE2( self, main ):
        """
        - Set up cell
            - Create cell file
            - Set cell file
            - Verify cell file
        - Kill ONOS process
        - Uninstall ONOS cluster
        - Verify ONOS start up
        - Install ONOS cluster
        - Connect to cli
        """

        main.numCtrls = int( main.maxNodes )

        main.case( "Starting up " + str( main.numCtrls ) +
                   " node(s) ONOS cluster" )

        main.log.info( "Safety check, killing all ONOS processes" +
                       " before initiating environment setup" )

        tempOnosIp = []
        for i in range( main.numCtrls ):
            tempOnosIp.append( main.ONOSip[i] )

        if main.params['CASE2']['incPackaging'] == "true":
            main.step("Create onos cell file with: " + main.apps)
            main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "temp",
                                       main.Mininet1.ip_address, main.apps, tempOnosIp )

            main.step( "Apply cell to environment" )
            cellResult = main.ONOSbench.setCell( "temp" )
            verifyResult = main.ONOSbench.verifyCell()
            stepResult = cellResult and verifyResult
            utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully applied cell to " + \
                                        "environment",
                                 onfail="Failed to apply cell to environment " )


            main.step( "Creating ONOS package" )
            packageResult = main.ONOSbench.onosPackage(opTimeout=240)
            stepResult = packageResult
            utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully created ONOS package",
                                 onfail="Failed to create ONOS package" )
            time.sleep( main.startUpSleep )

            main.step( "Uninstalling ONOS package" )
            onosUninstallResult = main.TRUE
            for i in range( main.numCtrls ):
                onosUninstallResult = onosUninstallResult and \
                    main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[ i ] )
            stepResult = onosUninstallResult
            utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully uninstalled ONOS package",
                                 onfail="Failed to uninstall ONOS package" )
            time.sleep( main.startUpSleep )

        else:
            main.log.info("onos Packaging Skipped!")

        main.step( "Installing ONOS package" )
        onosInstallResult = main.TRUE
        for i in range( main.numCtrls ):
            onosInstallResult = onosInstallResult and \
                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
        stepResult = onosInstallResult
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully installed ONOS package",
                                 onfail="Failed to install ONOS package" )
        time.sleep( main.startUpSleep )

        main.step( "Starting ONOS service" )
        stopResult = main.TRUE
        startResult = main.TRUE
        onosIsUp = main.TRUE

        for i in range( main.numCtrls ):
            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
        if onosIsUp == main.TRUE:
            main.log.report( "ONOS instance is up and ready" )
        else:
            main.log.report( "ONOS instance may not be up, stop and " +
                             "start ONOS again " )
            for i in range( main.numCtrls ):
                stopResult = stopResult and \
                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
            for i in range( main.numCtrls ):
                startResult = startResult and \
                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
        stepResult = onosIsUp and stopResult and startResult
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="ONOS service is ready",
                                 onfail="ONOS service did not start properly" )

        main.step( "Start ONOS cli" )
        cliResult = main.TRUE
        for i in range( i, main.numCtrls ):
            cliResult = cliResult and \
                        main.ONOScli1.startCellCli( )
            main.log.info("ONOSip is: " + main.ONOScli1.ip_address)
        stepResult = cliResult
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully start ONOS cli",
                                 onfail="Failed to start ONOS cli" )



    def CASE10( self, main ):
        '''
            Start Mininet
        '''
        import time

        main.case( "Enable openflow-base on onos and start Mininet." )

        main.step("Activate openflow-base App")
        app = main.params['CASE10']['app']
        stepResult = main.ONOScli1.activateApp( app )
        time.sleep(main.cfgSleep)
        main.log.info(stepResult)
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully activate " + app,
                                 onfail="Failed to activate app " + app )

        time.sleep(main.cfgSleep)


        main.step( "Configure AdaptiveFlowSampling ")
        stepResult = main.ONOScli1.setCfg( component = "org.onosproject.provider.of.flow.impl.OpenFlowRuleProvider",
                                   propName = "adaptiveFlowSampling ",  value = main.params['CASE10']['adaptiveFlowenabled'])
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="App Configuration Succeeded! ",
                                 onfail="App Configuration Failed!" )
        time.sleep(main.cfgSleep)

        main.step( "Setup Mininet Linear Topology with " + str(main.numSw) + " switches" )
        argStr = main.params['CASE10']['mnArgs'].format(main.numSw)
        stepResult = main.Mininet1.startNet( args = argStr )

        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully loaded topology",
                                 onfail="Failed to load topology" )

        time.sleep( main.startMNSleep )

        main.step( "Assign switches to controller" )
        for i in range(1, main.numSw + 1):
            main.Mininet1.assignSwController( "s" + str(i), main.ONOSip[0] )

        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully assigned switch to controller",
                                 onfail="Failed to assign switch to controller" )

        main.deviceIdPrefix = "of:"

        time.sleep( main.startMNSleep )

    def CASE11( self, main ):
        '''
            Start Null Provider
        '''
        import time

        main.case( "Setup Null Provider for linear Topology" )

        main.step("Activate Null Provider App")
        stepResult = main.ONOSbench.onosCli( ONOSIp = main.ONOSip[0],
                                             cmdstr = "app activate org.onosproject.null" )
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully activated org.onosproject.null",
                                 onfail="Failed to activate org.onosproject.null" )
        time.sleep( main.cfgSleep)

        main.step( "Setup Null Provider Linear Topology with " + str(main.numSw) + " devices." )
        r1 = main.ONOSbench.onosCfgSet( main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "deviceCount " + str(main.numSw))
        r2 = main.ONOSbench.onosCfgSet( main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "topoShape " + main.params['CASE11']['nullTopo'] )
        r3 = main.ONOSbench.onosCfgSet( main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "enabled " + main.params['CASE11']['nullStart'])
        stepResult = r1 & r2 & r3
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="App Configuration Succeeded! ",
                                 onfail="App Configuration Failed!" )
        time.sleep( main.cfgSleep )

        main.log.info("Check to make sure null providers are configured correctly.")
        main.ONOSbench.handle.sendline("onos $OC1 summary")
        stepResult = main.ONOSbench.handle.expect(":~")
        main.log.info("ONOS Summary: " + main.ONOSbench.handle.before)

        main.deviceIdPrefix = "null:"

        time.sleep( main.startMNSleep )



    def CASE1000( self, main ):
        '''
            create JSON object with batched flows
        '''
        import numpy
        import time
        from pprint import pprint

        main.case( "Create a json object for the batched flows" )

        main.step( "Parse batch creation information" )
        main.batchSize = int(main.params['CASE1000']['batchSize'])
        main.log.info("Number of flows in a batch is:" + str(main.batchSize))

        main.flowJsonBatchList = []
        startSw = 1

        main.step("Creating a full list of batches")
        for index in range(1, int(main.params['CASE1000']['batches']) + 1):
            if startSw <= main.numSw:
                ind = startSw
            else:
                startSw = 1
                ind = startSw

            main.log.info("Creating batch: " + str(index))
            flowJsonBatch = main.ONOSrest.createFlowBatch( numSw = main.numSw,
                                                           swIndex = ind,
                                                           batchSize = main.batchSize,
                                                           batchIndex = index,
                                                           deviceIdpreFix=main.deviceIdPrefix,
                                                           ingressPort = 2,
                                                           egressPort = 3)
            main.flowJsonBatchList.append(flowJsonBatch)

            startSw += 1
        main.log.info( "Number of items created in the batch list is: " + str(len(main.flowJsonBatchList)))

    def CASE2100(self, main):
        '''
            Posting flow batches using threads
        '''
        main.case("Using REST API /flows/{} to post flow batch - multi-threads")
        main.step("Using REST API /flows/{} to post flow batch - multi-threads")

        from Queue import Queue
        from threading import Thread
        import time
        import json

        main.threadID = 0
        main.addedBatchList = []
        q = Queue()
        tAllAdded = 0

        def postWorker(id):
            while True:
                item = q.get()
                #print json.dumps(item)
                status,response = main.ONOSrest.sendFlowBatch(batch = item)
                main.log.info("Thread {} is working on posting. ".format(id))
                #print json.dumps(response)
                main.addedBatchList.append(response[1])
                q.task_done()

        for i in range( int( main.params['CASE2100']['numThreads'])):
            threadID = "ThreadID-" + str(i)
            t = Thread(target = postWorker, name = threadID, args=(threadID,) )
            t.daemon = True
            t.start()

        tStartPost = time.time()
        for item in main.flowJsonBatchList:
            q.put(item)

        q.join()
        tLastPostEnd = time.time()

        main.step("Check to ensure all flows are in added state.")
        #pprint(main.addedBatchList)
        resp = main.FALSE
        while resp != main.TRUE and ( tAllAdded - tLastPostEnd < int (main.params['CASE2100']['chkFlowTO']) ):
            if main.params['CASE2100']['RESTchkFlow'] == main.TRUE:
                resp = main.ONOSrest.checkFlowsState()
            else:
                handle = main.CLIs[0].flows(state = " |grep PEND|wc -l", jsonFormat=False)
                main.log.info("handle returns PENDING flows: " + handle)
                if handle == "0":
                    resp = main.TRUE

            time.sleep( main.chkFlowSleep )
            tAllAdded = time.time()

        if tAllAdded - tLastPostEnd >= int (main.params['CASE2100']['chkFlowTO']):
            main.log.warn("ONOS Flows still in pending state after: {} seconds.".format(tAllAdded - tLastPostEnd))

        main.numFlows = int(main.params['CASE1000']['batches']) *\
                                                    int(main.params['CASE1000']['batchSize'])
        main.log.info("Total number of flows: " + str (main.numFlows) )
        main.elapsePOST = tLastPostEnd-tStartPost
        main.log.info("Total POST elapse time: " + str( main.elapsePOST ) )
        main.log.info("Rate of ADD Controller response: " + str(main.numFlows / ( main.elapsePOST )))

        main.POSTtoCONFRM = tAllAdded - tLastPostEnd
        main.log.info("Elapse time from end of last REST POST to Flows in ADDED state: " +\
                      str( main.POSTtoCONFRM ))
        main.log.info("Rate of Confirmed Batch Flow ADD is (flows/sec): " +
                      str( main.numFlows / main.POSTtoCONFRM ))
        main.log.info("Number of flow Batches in the addedBatchList is: " +
                      str( len(main.addedBatchList)))

    def CASE3100(self, main):
        '''
            DELETE flow batches using threads
        '''
        main.case("Using REST API /flows/{} to delete flow batch - multi-threads")
        main.step("Using REST API /flows/{} to delete flow batch - multi-threads")

        from Queue import Queue
        from threading import Thread
        import time
        import json

        main.threadID = 0
        q = Queue()
        tAllRemoved = 0

        main.log.info("Number of flow batches at start of remove: " + str( len( main.addedBatchList)))
        def removeWorker(id):
            while True:
                item = q.get()
                response = main.ONOSrest.removeFlowBatch(batch = json.loads(item) )
                main.log.info("Thread {} is working on deleting. ".format(id))
                q.task_done()

        for i in range( int( main.params['CASE2100']['numThreads'])):
            threadID = "ThreadID-" + str(i)
            t = Thread(target = removeWorker, name = threadID, args=(threadID,) )
            t.daemon = True
            t.start()

        tStartDelete = time.time()
        for item in main.addedBatchList:
            q.put(item)

        q.join()
        tLastDeleteEnd = time.time()
        main.log.info("Number of flow batches at end of remove: " + str( len( main.addedBatchList)))

        main.step("Check to ensure all flows are in added state.")
        #pprint(main.addedBatchList)
        resp = main.FALSE
        while resp != main.TRUE and ( tAllRemoved - tLastDeleteEnd < int (main.params['CASE3100']['chkFlowTO']) ):
            if main.params['CASE3100']['RESTchkFlow'] == main.TRUE:
                resp = main.ONOSrest.checkFlowsState()
            else:
                handle = main.CLIs[0].flows(state = " |grep PEND|wc -l", jsonFormat=False)
                main.log.info("handle returns PENDING flows: " + handle)
                if handle == "0":
                    resp = main.TRUE
            time.sleep( main.chkFlowSleep )
            tAllRemoved = time.time()

        if tLastDeleteEnd - tLastDeleteEnd >= int (main.params['CASE2100']['chkFlowTO']):
            main.log.warn("ONOS Flows still in pending state after: {} seconds.".format(tAllRemoved - tLastDeleteEnd))

        main.numFlows = int(main.params['CASE1000']['batches']) *\
                                                    int(main.params['CASE1000']['batchSize'])
        main.log.info("Total number of flows: " + str (main.numFlows) )
        main.elapseDELETE = tLastDeleteEnd-tStartDelete
        main.log.info("Total DELETE elapse time: " + str( main.elapseDELETE ))
        main.log.info("Rate of DELETE Controller response: " + str(main.numFlows / ( main.elapseDELETE )))

        main.DELtoCONFRM = tAllRemoved - tLastDeleteEnd
        main.log.info("Elapse time from end of last REST DELETE to Flows in REMOVED state: " +\
                      str( main.DELtoCONFRM ))
        main.log.info("Rate of Confirmed Batch Flow REMOVED is (flows/sec): " + str( main.numFlows / main.DELtoCONFRM))

    def CASE100(self,main):
        from pprint import pprint

        main.case( "Check to ensure onos flows." )

        resp = main.ONOSrest.checkFlowsState()
        #pprint(resp)

    def CASE210(self,main):
        main.case("Log test results to a data file")
        main.step("Write test resulted data to a data file")
        main.scale = main.maxNodes

        try:
            dbFileName="/tmp/SCPFbatchFlowRespData"
            dbfile = open(dbFileName, "w+")
            temp = "'" + main.commit + "',"
            temp += "'" + str( main.scale ) + "',"
            temp += "'" + main.cluster + "',"
            temp += "'" + str( main.elapsePOST ) + "',"
            temp += "'" + str( main.POSTtoCONFRM ) + "',"
            temp += "'" + str ( main.elapseDELETE ) + "',"
            temp += "'" + str ( main.DELtoCONFRM ) + "'\n"
            dbfile.write( temp )
            dbfile.close()
            stepResult = main.TRUE
        except IOError:
            main.log.warn("Error opening " + dbFileName + " to write results.")
            stepResult = main.FALSE

        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Succeeded to write results to datafile",
                                 onfail="Failed to write results to datafile " )
        
    def CASE110( self, main ):
        '''
        Report errors/warnings/exceptions
        '''
        main.log.info("Error report: \n" )
        main.ONOSbench.logReport( main.ONOSip[ 0 ],
                                  [ "INFO",
                                    "FOLLOWER",
                                    "WARN",
                                    "flow",
                                    "ERROR",
                                    "Except" ],
                                  "s" )
        #main.stop()

