"""
Copyright 2018 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/>.
"""

import time

def setupTest( main, test_idx, onosNodes ):
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    import tests.USECASE.SegmentRouting.dependencies.cfgtranslator as translator

    try:
        skipPackage = False
        init = False
        if not hasattr( main, "apps" ):
            init = True
            lib.initTest( main )
        # Skip onos packaging if the cluster size stays the same
        if not init and onosNodes == main.Cluster.numCtrls:
            skipPackage = True

        main.resultFileName = "CASE%03d" % test_idx
        main.Cluster.setRunningNode( onosNodes )
        lib.installOnos( main, skipPackage=skipPackage, cliSleep=5 )
        # Load configuration files
        main.step( "Load configurations" )
        main.cfgName = "TEST_CONFIG_ipv4=1_ipv6=1" if hasattr( main, "Mininet1" ) else main.params[ "DEPENDENCY" ][ "confName" ]
        if main.useBmv2:
            # Translate configuration file from OVS-OFDPA to BMv2 driver
            translator.bmv2ToOfdpa( main )  # Try to cleanup if switching between switch types
            switchPrefix = main.params[ 'DEPENDENCY' ].get( 'switchPrefix', "bmv2" )
            translator.ofdpaToBmv2( main, switchPrefix=switchPrefix )
        else:
            translator.bmv2ToOfdpa( main )
        lib.loadJson( main )
        time.sleep( float( main.params[ "timers" ][ "loadNetcfgSleep" ] ) )
        main.cfgName = "common" if hasattr( main, "Mininet1" ) else main.params[ "DEPENDENCY" ][ "confName" ]
        lib.loadMulticastConfig( main )
        lib.loadHost( main )

        if hasattr( main, "Mininet1" ):
            # Run the test with Mininet
            mininet_args = " --dhcp=1 --routers=1 --ipv6=1 --ipv4=1"
            if main.useBmv2:
                mininet_args += ' --switch %s' % main.switchType
                main.log.info( "Using %s switch" % main.switchType )
            lib.startMininet( main, main.params[ "DEPENDENCY" ][ "topology" ], args=mininet_args )
            time.sleep( float( main.params[ "timers" ][ "startMininetSleep" ] ) )
        else:
            # Run the test with physical devices
            lib.connectToPhysicalNetwork( main )

        # Create scapy components
        lib.startScapyHosts( main )
        # Verify host IP assignment
        lib.verifyOnosHostIp( main )
        lib.verifyNetworkHostIp( main )
    except Exception as e:
        main.log.exception( "Error in setupTest" )
        main.skipCase( result="FAIL", msg=e )

def verifyMcastRoutes( main ):
    """
    Install multicast routes and check traffic
    """
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    for routeName in main.mcastRoutes.keys():
        installMcastRoute( main, routeName )
        lib.verifyMulticastTraffic( main, routeName, True )

def installMcastRoute( main, routeName ):
    """
    Install a multicast route
    """
    main.step( "Install {} multicast route".format( routeName ) )
    routeData = main.multicastConfig[ routeName ]
    src = main.mcastRoutes[ routeName ][ "src" ]
    dst = main.mcastRoutes[ routeName ][ "dst" ]
    main.Cluster.active( 0 ).CLI.mcastHostJoin( routeData[ "src" ][ src[ 0 ] ][ "ip" ], routeData[ "group" ],
                                                [ routeData[ "src" ][ i ][ "id" ] for i in src ],
                                                [ routeData[ "dst" ][ i ][ "id" ] for i in dst ] )
    time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )

def verifyMcastRouteRemoval( main, routeName ):
    """
    Verify removal of a multicast route
    """
    routeData = main.multicastConfig[ routeName ]
    main.step( "Remove {} route".format( routeName ) )
    main.Cluster.active( 0 ).CLI.mcastSinkDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ] )
    # TODO: verify the deletion

def verifyMcastSinkRemoval( main, routeName, sinkIndex, expect ):
    """
    Verify removal of a multicast sink
    """
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    routeData = main.multicastConfig[ routeName ]
    sinkId = routeData[ "dst" ][ sinkIndex ][ "id" ]
    main.step( "Remove sink {} of route {}".format( sinkId, routeName ) )
    main.Cluster.active( 0 ).CLI.mcastSinkDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ], sinkId )
    time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )
    lib.verifyMulticastTraffic( main, routeName, expect )

def verifyMcastSourceRemoval( main, routeName, sourceIndex, expect ):
    """
    Verify removal of a multicast source
    """
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    routeData = main.multicastConfig[ routeName ]
    sourceId = [ routeData[ "src" ][ sourceIndex ][ "id" ] ]
    main.step( "Remove source {} of route {}".format( sourceId, routeName ) )
    main.Cluster.active( 0 ).CLI.mcastSourceDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ], sourceId )
    time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )
    lib.verifyMulticastTraffic( main, routeName, expect )

def verifyMcastRemoval( main, removeDHT1=True ):
    """
    Verify removal of IPv6 route, IPv4 sinks and IPv4 source
    """
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    verifyMcastRouteRemoval( main, "ipv6" )
    if removeDHT1:
        verifyMcastSinkRemoval( main, "ipv4", 0, [ False, True, True ] )
        verifyMcastSinkRemoval( main, "ipv4", 1, [ False, False, True ] )
    else:
        verifyMcastSinkRemoval( main, "ipv4", 2, [ True, True, False ] )
        verifyMcastSinkRemoval( main, "ipv4", 1, [ True, False, False ] )
    verifyMcastSourceRemoval( main, "ipv4", 0, False )

def verifyLinkDown( main, link, affectedLinkNum, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
    """
    Kill a batch of links and verify traffic
    Restore the links and verify traffic
    """
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    link = link if ( isinstance( link, list ) and isinstance( link[ 0 ], list ) ) else [ link ]
    # Kill the link(s)
    lib.killLinkBatch( main, link, int( main.params[ "TOPO" ][ "linkNum" ] ) - affectedLinkNum, int( main.params[ "TOPO" ][ "switchNum" ] ) )
    for routeName in expectList.keys():
        lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
    # Restore the link(s)
    lib.restoreLinkBatch( main, link, int( main.params[ "TOPO" ][ "linkNum" ] ), int( main.params[ "TOPO" ][ "switchNum" ] ) )
    if hostsToDiscover:
        main.Network.discoverHosts( hostList=hostsToDiscover )
    if hostLocations:
        lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
    for routeName in expectList.keys():
        lib.verifyMulticastTraffic( main, routeName, True )

def verifyPortDown( main, dpid, port, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
    """
    Disable a port and verify traffic
    Reenable the port and verify traffic
    """
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    # Disable the port(s)
    main.step( "Disable port {}/{}".format( dpid, port ) )
    main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state="disable" )
    time.sleep( 10 )
    for routeName in expectList.keys():
        lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
    # Reenable the port(s)
    main.step( "Enable port {}/{}".format( dpid, port ) )
    main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state="enable" )
    if hostsToDiscover:
        main.Network.discoverHosts( hostList=hostsToDiscover )
    if hostLocations:
        lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
    for routeName in expectList.keys():
        lib.verifyMulticastTraffic( main, routeName, True )

def verifySwitchDown( main, switchName, affectedLinkNum, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
    """
    Kill a batch of switches and verify traffic
    Recover the swithces and verify traffic
    """
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    switchName = switchName if isinstance( switchName, list ) else [ switchName ]
    # Kill the switch(es)
    lib.killSwitch( main, switchName, int( main.params[ "TOPO" ][ "switchNum" ] ) - len( switchName ), int( main.params[ "TOPO" ][ "linkNum" ] ) - affectedLinkNum )
    for routeName in expectList.keys():
        lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
    # Recover the switch(es)
    lib.recoverSwitch( main, switchName, int( main.params[ "TOPO" ][ "switchNum" ] ), int( main.params[ "TOPO" ][ "linkNum" ] ), True if hostsToDiscover else False, hostsToDiscover )
    if hostLocations:
        lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
    for routeName in expectList.keys():
        lib.verifyMulticastTraffic( main, routeName, True )

def verifyOnosDown( main, expectList={ "ipv4": True, "ipv6": True } ):
    """
    Kill and recover ONOS instances Sequencially and check traffic
    """
    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
    import json
    numCtrls = len( main.Cluster.runningNodes )
    links = len( json.loads( main.Cluster.next().links() ) )
    switches = len( json.loads( main.Cluster.next().devices() ) )
    for ctrl in xrange( numCtrls ):
        # Kill node
        lib.killOnos( main, [ ctrl ], switches, links, ( numCtrls - 1 ) )
        main.Cluster.active(0).CLI.balanceMasters()
        time.sleep( float( main.params[ 'timers' ][ 'balanceMasterSleep' ] ) )
        for routeName in expectList.keys():
            lib.verifyMulticastTraffic( main, routeName, True )
        # Recover node
        lib.recoverOnos( main, [ ctrl ], switches, links, numCtrls )
        main.Cluster.active(0).CLI.balanceMasters()
        time.sleep( float( main.params[ 'timers' ][ 'balanceMasterSleep' ] ) )
        for routeName in expectList.keys():
            lib.verifyMulticastTraffic( main, routeName, True )
