"""
Copyright 2015 Open Networking Foundation (ONF)

Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>

    TestON is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    TestON is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with TestON.  If not, see <http://www.gnu.org/licenses/>.
"""

"""
    Wrapper function for FuncTopo
    Includes onosclidriver and mininetclidriver functions
"""
import time
import json
import re

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

def getTimestampFromString( main, targetString ):
    #Get time string from the target string
    try:
        assert type( targetString ) is str
        timeString = targetString.split( ' | ' )
        timeString = timeString[ 0 ]
        from datetime import datetime
        # convert time string to timestamp
        t = datetime.strptime( timeString, "%Y-%m-%d %H:%M:%S,%f" )
        import time
        timestamp = time.mktime( t.timetuple() )
        timestamp += int( t.microsecond / 1000 ) / 1000.0
        return timestamp
    except AssertionError:
        main.log.error( "Got nothing firom log" )
        return -1
    except IndexError:
        main.log.error( "Time string index error" )
        return -1
    except ValueError:
        main.log.error( "Got wrong string from log" )
        return -1

def getRoleRequestTimeFromTshark( main ):
    try:
        main.log.info( "Get role request time" )
        with open(main.tsharkResultPath, "r" ) as resultFile:
            resultText = resultFile.readlines()
            # select the last role request string
            roleRequestString = resultText[ len( resultText ) - 1 ]
            main.log.info( roleRequestString )
            # get timestamp from role request string
            roleRequestTime = roleRequestString.split( " " )
            resultFile.close()
            return float(roleRequestTime[1])
    except IndexError:
        main.log.error("Got wrong role request string from Tshark file")
        return -1

def compareTimeDiffWithRoleRequest(main, term, Mode, index=0 ):
    '''
    Description:
        Compare the time difference between the time of target term and the time of role request
        Inclides onosclidriver functions

    '''
    try:
        termInfo = main.Cluster.active( index ).CLI.logSearch( mode=Mode, searchTerm=term )
        termTime = getTimestampFromString( main, termInfo[ 0 ] )
        roleRequestTime = getRoleRequestTimeFromTshark( main )
        if termTime == -1 or roleRequestTime == -1:
            main.writeData = -1
            main.log.error( "Can't compare the difference with role request time" )
            return -1
        # Only concern about the absolute value of difference.
        return abs( roleRequestTime - termTime )
    except IndexError:
        main.log.error( "Catch the wrong information of search term " )
        main.writeData = -1
        return -1

def getInfoFromLog( main, term1, mode1, term2, mode2, index=0, funcMode='TD' ):
    '''
    Description:
        Get needed informations of the search term from karaf.log
        Includes onosclidriver functions
    Function mode:
        TD (time difference):
            Get time difference between start and end
            Term1: startTerm
            Term2: endTerm
        DR (disconnect rate):
            Get switch disconnect rate
            Term1: disconnectTerm
            Term2: connectTerm

    '''
    try:
        termInfo1 = main.Cluster.active( index ).CLI.logSearch( mode=mode1, searchTerm=term1 )
        termInfo2 = main.Cluster.active( index ).CLI.logSearch( mode=mode2, searchTerm=term2 )
        if funcMode == 'TD':
            startTime = getTimestampFromString( main, termInfo1[0] )
            endTime = getTimestampFromString ( main, termInfo2[0] )
            if startTime == -1 or endTime == -1:
                main.log.error( "Wrong Time!" )
                main.writeData = -1
                return -1
            return endTime - startTime
        if funcMode == 'DR':
            #In this mode, termInfo1 means the total number of switch disconnection and
            #termInfo2 means the total number of new switch connection
            #termInfo2 - termInfo1 means the actual real number of switch connection.
            disconnection = int( termInfo1 ) * 1.0
            expectConnection = int( main.currScale ) ** 2
            realConnection = int( termInfo2 ) - int( termInfo1 )
            if expectConnection != realConnection:
                main.log.error( "The number of real switch connection doesn't match the number of expected connection" )
                main.writeData = -1
                return -1
            rate = disconnection / expectConnection
            return rate
    except IndexError:
        main.log.error( "Catch the wrong information of search term" )
        main.writeData = -1
        return -1

def testTopology( main, topoFile='', args='', mnCmd='', timeout=300, clean=True ):
    """
    Description:
        This function combines different wrapper functions in this module
        to simulate a topology test
    Test Steps:
        - Load topology
        - Discover topology
        - Compare topology
        - pingall
        - Bring links down
        - Compare topology
        - pingall
        - Bring links up
        - Compare topology
        - pingall
    Options:
        clean: Does sudo mn -c to clean mininet residue
        Please read mininetclidriver.py >> startNet( .. ) function for details
    Returns:
        Returns main.TRUE if the test is successful, main.FALSE otherwise
    """
    testTopoResult = main.TRUE
    compareTopoResult = main.TRUE
    topoObjectResult = main.TRUE
    stopResult = main.TRUE

    if clean:
        # Cleans minient
        stopResult = stopMininet( main )

    # Restart ONOS to clear hosts test new mininet topology
    reinstallOnosResult = reinstallOnos( main )

    # Starts topology
    startResult = startNewTopology( main, topoFile, args, mnCmd, timeout=timeout )
    # onos needs time to see the links
    time.sleep(15)

    # Gets list of switches in mininet
    #assignSwitch( main )

    testTopoResult = startResult and topoObjectResult


    return testTopoResult

def startNewTopology( main, topoFile='', args='', mnCmd='', timeout=900 ):
    """
    Description:
        This wrapper function starts new topology
    Options:
        Please read mininetclidriver.py >> startNet( .. ) function for details
    Return:
        Returns main.TRUE if topology is successfully created by mininet,
        main.FALSE otherwise
    NOTE:
        Assumes Mininet1 is the name of the handler
    """
    assert main, "There is no main variable"
    assert main.Mininet1, "Mininet 1 is not created"
    result = main.TRUE

    main.log.info( main.topoName + ": Starting new Mininet topology" )

    # log which method is being used
    if topoFile:
        main.log.info( main.topoName + ": Starting topology with " +
                       topoFile + "topology file" )
    elif not topoFile and not mnCmd:
        main.log.info( main.topoName + ": Starting topology using" +
                       " the topo file" )
    elif topoFile and mnCmd:
        main.log.error( main.topoName + ": You can only use one " +
                        "method to start a topology" )
    elif mnCmd:
        main.log.info( main.topoName + ": Starting topology with '" +
                       mnCmd + "' Mininet command" )


    result = main.Mininet1.startNet( topoFile=topoFile,
                                     args=args,
                                     mnCmd=mnCmd,
                                     timeout=timeout)

    return result

def stopMininet( main ):
    """
        Stops current topology and execute mn -c basically triggers
        stopNet in mininetclidrivers

        NOTE: Mininet should be running when issuing this command other wise
        the this function will cause the test to stop
    """
    stopResult = main.TRUE
    stopResult = main.Mininet1.stopNet()
    time.sleep( 30 )
    if not stopResult:
        main.log.info(  main.topoName + ": Did not stop Mininet topology" )
    return stopResult

def compareTopo( main ):
    """
        Compare topology( devices, links, ports, hosts ) between ONOS and
        mininet using sts
    """
    try:
        from tests.dependencies.topology import Topology
    except ImportError:
        main.log.error( "Topology not found exiting the test" )
        main.cleanAndExit()
    try:
        main.topoRelated
    except ( NameError, AttributeError ):
        main.topoRelated = Topology()
    return main.topoRelated.compareTopos( main.Mininet1 )

def assignSwitch( main ):
    """
        Returns switch list using getSwitch in Mininet driver
    """
    switchList = []
    assignResult = main.TRUE
    switchList =  main.Mininet1.getSwitch()
    assignResult = main.Mininet1.assignSwController( sw=switchList,
                                                     ip=main.Cluster.active( 0 ).ipAddress,
                                                     port=6633 )

    for sw in switchList:
        response = main.Mininet1.getSwController( sw )
        if re.search( "tcp:" + main.Cluster.active( 0 ).ipAddress, response ):
            assignResult = assignResult and main.TRUE
        else:
            assignResult = main.FALSE

    return switchList

def connectivity( main, timeout=900, shortCircuit=True, acceptableFailed=20 ):
    """
        Use fwd app and pingall to discover all the hosts
    """
    activateResult = main.TRUE
    appCheck = main.TRUE
    getDataResult = main.TRUE
    main.log.info( main.topoName + ": Activating reactive forwarding app " )
    activateResult = main.Cluster.active( 0 ).activateApp( "org.onosproject.fwd" )

    if main.hostsData:
        main.hostsData = {}
    for ctrl in main.Cluster.active():
        appCheck = appCheck and ctrl.CLI.appToIDCheck()
        if appCheck != main.TRUE:
            main.log.warn( ctrl.CLI.apps() )
            main.log.warn( ctrl.CLI.appIDs() )

    time.sleep( main.fwdSleep )

    # Discover hosts using pingall
    pingResult = main.Mininet1.pingall( timeout=timeout,
                                        shortCircuit=shortCircuit,
                                        acceptableFailed=acceptableFailed )

    main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
    activateResult = main.Cluster.active( 0 ).deactivateApp( "org.onosproject.fwd" )
    for ctrl in main.Cluster.active():
        appCheck = appCheck and ctrl.CLI.appToIDCheck()
        if appCheck != main.TRUE:
            main.log.warn( ctrl.CLI.apps() )
            main.log.warn( ctrl.CLI.appIDs() )

    return pingResult

def getHostsData( main ):
    """
        Use fwd app and pingall to discover all the hosts
    """
    activateResult = main.TRUE
    appCheck = main.TRUE
    getDataResult = main.TRUE
    main.log.info( main.topoName + ": Activating reactive forwarding app " )
    activateResult = main.Cluster.active( 0 ).CLI.activateApp( "org.onosproject.fwd" )

    if main.hostsData:
        main.hostsData = {}
    for ctrl in main.Cluster.active():
        appCheck = appCheck and ctrl.CLI.appToIDCheck()
        if appCheck != main.TRUE:
            main.log.warn( ctrl.CLI.apps() )
            main.log.warn( ctrl.CLI.appIDs() )

    time.sleep( main.fwdSleep )
    # Discover hosts using pingall
    pingResult = main.Mininet1.pingall( timeout=900 )

    hostsJson = json.loads( main.Cluster.active( 0 ).CLI.hosts() )
    hosts = main.Mininet1.getHosts().keys()

    for host in hosts:
        main.hostsData[ host ] = {}
        main.hostsData[ host ][ 'mac' ] =  \
            main.Mininet1.getMacAddress( host ).upper()
        for hostj in hostsJson:
            if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
                main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
                main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
                main.hostsData[ host ][ 'location' ] = \
                            hostj[ 'locations' ][ 0 ][ 'elementId' ] + '/' + \
                            hostj[ 'locations' ][ 0 ][ 'port' ]
                main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]

    if activateResult and main.hostsData:
        main.log.info( main.topoName + ": Successfully used fwd app" +
                       " to discover hosts " )
        getDataResult = main.TRUE
    else:
        main.log.info( main.topoName + ": Failed to use fwd app" +
                       " to discover hosts " )
        getDataResult = main.FALSE

    main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
    activateResult = main.Cluster.active( 0 ).CLI.deactivateApp( "org.onosproject.fwd" )
    for ctrl in main.Cluster.active():
        appCheck = appCheck and ctrl.CLI.appToIDCheck()
        if appCheck != main.TRUE:
            main.log.warn( ctrl.CLI.apps() )
            main.log.warn( ctrl.CLI.appIDs() )

    # This data can be use later for intents
    print main.hostsData

    return getDataResult

def reinstallOnos( main ):
    """
    Description:
        Stop and start ONOS that clears hosts,devices etc. in order to test
        new mininet topology
    Return:
        Retruns main.TRUE for a successful restart, main.FALSE otherwise.
    """
    stopResult = []
    startResult = []
    onosIsUpResult = []
    restartResult = main.TRUE

    uninstallResult = main.testSetUp.uninstallOnos( main.Cluster, False )
    if uninstallResult != main.TRUE:
        restartResult = main.FALSE
    installResult = main.testSetUp.installOnos( main.Cluster, False )
    if installResult != main.TRUE:
        restartResult = main.FALSE

    secureSshResult = main.testSetUp.setupSsh( main.Cluster )
    if secureSshResult != main.TRUE:
        restartResult = main.FALSE

    for ctrl in main.Cluster.runningNodes:
        onosIsUpResult.append( main.ONOSbench.isup( ctrl.ipAddress ) )

    if all( result == main.TRUE for result in onosIsUpResult ):
        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 ctrl in main.Cluster.runningNodes:
            stopResult.append( main.ONOSbench.onosStop( ctrl.ipAddress ) )

        if all( result == main.TRUE for result in stopResult ):
            main.log.info( main.topoName + ": Successfully stop ONOS cluster" )
        else:
            main.log.error( main.topoName + ": Failed to stop ONOS cluster" )

        for ctrl in main.Cluster.runningNodes:
            startResult.append( main.ONOSbench.onosStart( ctrl.ipAddress ) )

        if all( result == main.TRUE for result in startResult ):
            main.log.info( main.topoName + ": Successfully start ONOS cluster" )
        else:
            main.log.error( main.topoName + ": Failed to start ONOS cluster" )

    main.log.info( main.topoName + ": Starting ONOS CLI" )
    cliResult = main.testSetUp.startOnosClis( main.Cluster )
    if cliResult != main.TRUE:
        restartResult = main.FALSE


    return restartResult



