"""
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/>


    These functions are for use with the Network config system
"""
import time


def compareCfg( main, gossipTime=None ):
    """
    Compare the network configurations across all nodes in the network
    gossipTime is the number of seconds each gossip round take for the netCfg maps
    """
    main.step( "Check net config" )
    if gossipTime:
        time.sleep( gossipTime * main.Cluster.numCtrls )
    responses = []
    result = utilities.retry( f=checkNodeResponses,
                              retValue=False,
                              kwargs={'main' : main,'responses' : responses},
                              sleep = main.retrysleep,
                              attempts = main.retrytimes )
    utilities.assert_equals( expect=True,
                             actual=result,
                             onpass="Net Cfg is the same on all nodes",
                             onfail="Check Net Cfg failed. Check above messages." )


def checkNodeResponses ( main, responses ):
    numberOfFailedNodes = 0  # Tracks the number of nodes that failed to get net configuration
    for ctrl in main.Cluster.active():
        response = ctrl.REST.getNetCfg( )
        responses.append( ctrl.REST.pprint( response ) )
        if response == main.FALSE:
            numberOfFailedNodes += 1

    compare = [ i == responses[ 0 ] for i in responses ]
    if numberOfFailedNodes == 0 and all( compare ):
        return True

    # Failed, providing feedback on cli
    if numberOfFailedNodes > 0:
        main.log.warn( numberOfFailedNodes + " node(s) failed to GET Net Config" )
    if not all( compare ):
        main.log.debug( "Net Cfg is different on some nodes. Net Config results:" )
        for i in responses:
            main.log.debug( i )
    return False

def checkDeviceAnnotations( main, jsonObj, sw ):
    id = str( sw.get( 'id' ) )
    keys = [ 'name', 'owner', 'rackAddress' ]
    correct = True
    for k in keys:
        if str( sw.get( 'annotations', {} ).get( k ) ) != str( jsonObj[ k ] ) :
            correct = False
            main.log.debug( "{} is wrong on switch: ".format( k ) + id )
    if not correct:
        main.log.error( "Annotations for switch " + id  + " are incorrect: {}".format( sw ) )
    return correct


def checkAllDeviceAnnotations( main, json ):
    devices = main.Cluster.active( 0 ).REST.devices( )
    id = "of:0000000000000001"
    i = 1
    result = [ ]
    try:
        for sw in json.loads( devices ):
            if id in sw.get( 'id' ):
                jsonObj = getattr( main, "s" + str( i ) + "Json" )
                isDeviceAnnotationCorrect = checkDeviceAnnotations( main, jsonObj, sw )
                result.append( isDeviceAnnotationCorrect )
                i += 1
                id = "of:000000000000000" + str( i )
    except( TypeError, ValueError ):
        main.log.error( "Problem loading device" )
        return False
    return all( result )
