"""
Copyright 2016 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 re


class ONOSSetup:
    main = None

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

    def envSetupDescription( self, includeCaseDesc=True ):
        """
        Introduction part of the test. It will initialize some basic vairables.
        """
        if includeCaseDesc:
            main.case( "Constructing test variables and building ONOS package" )
            main.caseExplanation = "For loading from params file, and pull" + \
                                   " and build the latest ONOS package"
        main.step( "Constructing test variables" )
        try:
            from tests.dependencies.Cluster import Cluster
        except ImportError:
            main.log.error( "Cluster not found. exiting the test" )
            main.cleanAndExit()
        try:
            main.Cluster
        except ( NameError, AttributeError ):
            main.Cluster = Cluster( main.ONOScell.nodes )
        main.ONOSbench = main.Cluster.controllers[ 0 ].Bench
        main.testOnDirectory = re.sub( "(/tests)$", "", main.testsRoot )

    def gitPulling( self, includeCaseDesc=True ):
        """
        it will do git checkout or pull if they are enabled from the params file.
        """

        if includeCaseDesc:
            main.case( "Pull onos branch and build onos on Teststation." )

        gitPull = main.params[ 'GIT' ][ 'pull' ]
        gitBranch = main.params[ 'GIT' ][ 'branch' ]
        if gitPull == 'True':
            main.step( "Git Checkout ONOS branch: " + gitBranch )
            stepResult = main.ONOSbench.gitCheckout( branch=gitBranch )
            utilities.assert_equals( expect=main.TRUE,
                                     actual=stepResult,
                                     onpass="Successfully checkout onos branch.",
                                     onfail="Failed to checkout onos branch. Exiting test..." )
            if not stepResult:
                main.cleanAndExit()

            main.step( "Git Pull on ONOS branch:" + gitBranch )
            stepResult = main.ONOSbench.gitPull()
            utilities.assert_equals( expect=main.TRUE,
                                     actual=stepResult,
                                     onpass="Successfully pull onos. ",
                                     onfail="Failed to pull onos. Exiting test ..." )
            if not stepResult:
                main.cleanAndExit()

        else:
            main.log.info( "Skipped git checkout and pull as they are disabled in params file" )

    def envSetup( self, includeGitPull=True, includeCaseDesc=True ):
        """
        Description:
            some environment setup for the test.
        Required:
            * includeGitPull - if wish to git pulling function to be executed.
        Returns:
            Returns main.TRUE
        """
        if includeGitPull:
            self.gitPulling( includeCaseDesc )

        try:
            from tests.dependencies.Cluster import Cluster
        except ImportError:
            main.log.error( "Cluster not found. exiting the test" )
            main.cleanAndExit()
        try:
            main.Cluster
        except ( NameError, AttributeError ):
            main.Cluster = Cluster( main.ONOScell.nodes )

        main.cellData = {}  # For creating cell file

        return main.TRUE

    def envSetupException( self, e ):
        """
        Description:
            handles the exception that might occur from the environment setup.
        Required:
            * includeGitPull - exceeption code e.
        """
        main.log.exception( e )
        main.cleanAndExit()

    def evnSetupConclusion( self, stepResult ):
        """
        Description:
            compare the result of the envSetup of the test.
        Required:
            * stepResult - Result of the envSetup.
        """
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully construct " +
                                        "test variables ",
                                 onfail="Failed to construct test variables" )

        url = self.generateGraphURL()
        main.log.wiki( url )

        main.commit = main.ONOSbench.getVersion( report=True )

    def generateGraphURL( self, width=525, height=350 ):
        """
        Description:
            Obtain the URL for the graph that corresponds to the test being run.
        """

        nodeCluster = main.params[ 'GRAPH' ][ 'nodeCluster' ]
        testname = main.TEST
        branch = main.ONOSbench.getBranchName()
        maxBuildsToShow = main.params[ 'GRAPH' ][ 'builds' ]

        return '<ac:structured-macro ac:name="html">\n' + \
                '<ac:plain-text-body><![CDATA[\n' + \
                '<img src="https://jenkins.onosproject.org/view/QA/job/postjob-' + \
                nodeCluster + \
                '/lastSuccessfulBuild/artifact/' + \
                testname + \
                '_' + \
                branch + \
                '_' + \
                maxBuildsToShow + \
                '-builds_graph.jpg", alt="' + \
                testname + \
                '", style="width:' + \
                str( width ) + \
                'px;height:' + \
                str( height ) + \
                'px;border:0"' + \
                '>' + \
                ']]></ac:plain-text-body>\n' + \
                '</ac:structured-macro>\n'

    def setNumCtrls( self, hasMultiNodeRounds ):
        """
        Description:
            Set new number of controllers if it uses different number of nodes.
            different number of nodes should be pre-defined in main.scale.
        Required:
            * hasMultiNodeRouds - if the test is testing different number of nodes.
        """
        if hasMultiNodeRounds:
            try:
                main.cycle
            except Exception:
                main.cycle = 0
            main.cycle += 1
            # main.scale[ 0 ] determines the current number of ONOS controllers
            main.Cluster.setRunningNode( int( main.scale.pop( 0 ) ) )

    def killingAllAtomix( self, cluster, killRemoveMax, stopAtomix ):
        """
        Description:
            killing atomix. It will either kill the current runningnodes or
            max number of the nodes.
        Required:
            * cluster - the cluster driver that will be used.
            * killRemoveMax - The boolean that will decide either to kill
            only running nodes ( False ) or max number of nodes ( True ).
            * stopAtomix - If wish to stop atomix before killing it. True for
            enable stop, False for disable stop.
        Returns:
            Returns main.TRUE if successfully killing it.
        """
        main.log.info( "Safety check, killing all Atomix processes" )
        return cluster.killAtomix( killRemoveMax, stopAtomix )

    def killingAllOnos( self, cluster, killRemoveMax, stopOnos ):
        """
        Description:
            killing the onos. It will either kill the current runningnodes or
            max number of the nodes.
        Required:
            * cluster - the cluster driver that will be used.
            * killRemoveMax - The boolean that will decide either to kill
            only running nodes ( False ) or max number of nodes ( True ).
            * stopOnos - If wish to stop onos before killing it. True for
            enable stop, False for disable stop.
        Returns:
            Returns main.TRUE if successfully killing it.
        """
        main.log.info( "Safety check, killing all ONOS processes" )
        return cluster.killOnos( killRemoveMax, stopOnos )

    def createApplyCell( self, cluster, newCell, cellName, cellApps,
                         mininetIp, useSSH, onosIps, installMax=False,
                         atomixClusterSize=None ):
        """
        Description:
            create new cell ( optional ) and apply it. It will also verify the
            cell.
        Required Arguments:
            * cluster - the cluster driver that will be used.
            * newCell - True for making a new cell and False for not making it.
            * cellName - The name of the cell.
            * cellApps - The onos apps string.
            * mininetIp - Mininet IP address.
            * useSSH - True for using ssh when creating a cell
            * onosIps - ip( s ) of the ONOS node( s ).
        Optional Arguments:
            * installMax
            * atomixClusterSize - The size of the atomix cluster. Defaults to same
                as ONOS Cluster size
        Returns:
            Returns main.TRUE if it successfully executed.
        """
        if atomixClusterSize is None:
            atomixClusterSize = len( cluster.runningNodes )
        atomixClusterSize = int( atomixClusterSize )
        cluster.setAtomixNodes( atomixClusterSize )
        atomixIps = [ node.ipAddress for node in cluster.atomixNodes ]
        main.log.info( "Atomix Cluster Size = {} ".format( atomixClusterSize ) )
        if newCell:
            cluster.createCell( cellName, cellApps, mininetIp, useSSH, onosIps,
                                atomixIps, installMax )
        main.step( "Apply cell to environment" )
        stepResult = cluster.applyCell( cellName )
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="Successfully applied cell to " +
                                       "environment",
                                 onfail="Failed to apply cell to environment" )
        return stepResult

    def uninstallAtomix( self, cluster, uninstallMax ):
        """
        Description:
            uninstalling atomix and verify the result.
        Required:
            * cluster - a cluster driver that will be used.
            * uninstallMax - True for uninstalling max number of nodes
                False for uninstalling the current running nodes.
        Returns:
            Returns main.TRUE if it successfully uninstalled.
        """
        main.step( "Uninstalling Atomix" )
        atomixUninstallResult = cluster.uninstallAtomix( uninstallMax )
        utilities.assert_equals( expect=main.TRUE,
                                 actual=atomixUninstallResult,
                                 onpass="Successfully uninstalled Atomix",
                                 onfail="Failed to uninstall Atomix" )
        return atomixUninstallResult

    def uninstallOnos( self, cluster, uninstallMax ):
        """
        Description:
            uninstalling onos and verify the result.
        Required:
            * cluster - a cluster driver that will be used.
            * uninstallMax - True for uninstalling max number of nodes
            False for uninstalling the current running nodes.
        Returns:
            Returns main.TRUE if it successfully uninstalled.
        """
        main.step( "Uninstalling ONOS package" )
        onosUninstallResult = cluster.uninstallOnos( uninstallMax )
        utilities.assert_equals( expect=main.TRUE,
                                 actual=onosUninstallResult,
                                 onpass="Successfully uninstalled ONOS package",
                                 onfail="Failed to uninstall ONOS package" )
        return onosUninstallResult

    def buildOnos( self, cluster ):
        """
        Description:
            build the onos using bazel build onos and verify the result
        Required:
            * cluster - the cluster driver that will be used.
        Returns:
            Returns main.TRUE if it successfully built.
        """
        main.step( "Creating ONOS package" )
        packageResult = main.ONOSbench.bazelBuild()
        utilities.assert_equals( expect=main.TRUE,
                                 actual=packageResult,
                                 onpass="Successfully created ONOS package",
                                 onfail="Failed to create ONOS package" )
        return packageResult

    def installAtomix( self, cluster, parallel=True ):
        """
        Description:
            Installing atomix and verify the result
        Required:
            * cluster - the cluster driver that will be used.
            False for installing current running nodes only.
        Returns:
            Returns main.TRUE if it successfully installed
        """
        main.step( "Installing Atomix" )
        atomixInstallResult = main.TRUE

        atomixInstallResult = cluster.installAtomix( parallel )
        utilities.assert_equals( expect=main.TRUE,
                                 actual=atomixInstallResult,
                                 onpass="Successfully installed Atomix",
                                 onfail="Failed to install Atomix" )
        if not atomixInstallResult:
            main.cleanAndExit()
        return atomixInstallResult

    def installOnos( self, cluster, installMax, parallel=True ):
        """
        Description:
            Installing onos and verify the result
        Required:
            * cluster - the cluster driver that will be used.
            * installMax - True for installing max number of nodes
            False for installing current running nodes only.
        Returns:
            Returns main.TRUE if it successfully installed
        """
        main.step( "Installing ONOS package" )
        onosInstallResult = main.TRUE

        cluster.installOnos( installMax, parallel )
        utilities.assert_equals( expect=main.TRUE,
                                 actual=onosInstallResult,
                                 onpass="Successfully installed ONOS package",
                                 onfail="Failed to install ONOS package" )
        if not onosInstallResult:
            main.cleanAndExit()
        return onosInstallResult

    def setupSsh( self, cluster ):
        """
        Description:
            set up ssh to the onos and verify the result
        Required:
            * cluster - the cluster driver that will be used.
        Returns:
            Returns main.TRUE if it successfully setup the ssh to
            the onos.
        """
        main.step( "Set up ONOS secure SSH" )
        secureSshResult = cluster.ssh()
        utilities.assert_equals( expect=main.TRUE,
                                 actual=secureSshResult,
                                 onpass="Secured ONOS ssh",
                                 onfail="Failed to secure ssh" )
        return secureSshResult

    def checkOnosService( self, cluster ):
        """
        Description:
            Checking if the onos service is up and verify the result
        Required:
            * cluster - the cluster driver that will be used.
        Returns:
            Returns main.TRUE if it successfully checked
        """
        main.step( "Checking ONOS service" )
        stepResult = cluster.checkService()
        utilities.assert_equals( expect=main.TRUE,
                                 actual=stepResult,
                                 onpass="ONOS service is ready on all nodes",
                                 onfail="ONOS service did not start properly on all nodes" )
        return stepResult

    def startOnosClis( self, cluster ):
        """
        Description:
            starting Onos using onosCli driver and verify the result
        Required:
            * cluster - the cluster driver that will be used.
        Returns:
            Returns main.TRUE if it successfully started. It will exit
            the test if not started properly.
        """
        main.step( "Starting ONOS CLI sessions" )
        startCliResult = cluster.startCLIs()
        if not startCliResult:
            main.log.info( "ONOS CLI did not start up properly" )
            main.cleanAndExit()
        else:
            main.log.info( "Successful CLI startup" )
        utilities.assert_equals( expect=main.TRUE,
                                 actual=startCliResult,
                                 onpass="Successfully start ONOS cli",
                                 onfail="Failed to start ONOS cli" )
        return startCliResult

    def checkOnosNodes( self, cluster ):
        """
        Description:
            Checking if the onos nodes are in READY state
        Required:
            * cluster - the cluster driver that will be used.
        Returns:
            Returns main.TRUE if it successfully checked
        """
        main.step( "Checking ONOS nodes" )
        stepResult = utilities.retry( main.Cluster.nodesCheck,
                                      False,
                                      attempts=90 )

        utilities.assert_equals( expect=True,
                                 actual=stepResult,
                                 onpass="All ONOS nodes are in READY state",
                                 onfail="Not all ONOS nodes are in READY state" )

        if not stepResult:
            for ctrl in main.Cluster.active():
                main.log.debug( "{} components not ACTIVE: \n{}".format(
                    ctrl.name,
                    ctrl.CLI.sendline( "onos:scr-list | grep -v ACTIVE" ) ) )  #FIXME: This output has changed a lot
            main.log.error( "Failed to start ONOS, stopping test" )
            main.cleanAndExit()
        return main.TRUE

    def checkOnosApps( self, cluster, apps ):
        """
        Description:
            Checking if the onos applications are activated
        Required:
            * cluster - the cluster driver that will be used.
            * apps: list of applications that are expected to be activated
        Returns:
            Returns main.TRUE if it successfully checked
        """
        main.step( "Checking ONOS applications" )
        stepResult = utilities.retry( main.Cluster.appsCheck,
                                      False,
                                      args = [ apps ],
                                      sleep=5,
                                      attempts=90 )

        utilities.assert_equals( expect=True,
                                 actual=stepResult,
                                 onpass="All ONOS apps are activated",
                                 onfail="Not all ONOS apps are activated" )

        return main.TRUE if stepResult else main.FALSE

    def processList( self, functions, args ):
        if functions is not None:
            if isinstance( functions, list ):
                i = 0
                for f in functions:
                    f( *( args[ i ] ) ) if args is not None and args[ i ] is not None else f()
                    i += 1
            else:
                functions( *args ) if args is not None else functions()

    def ONOSSetUp( self, cluster, hasMultiNodeRounds=False, startOnos=True, newCell=True,
                   cellName="temp", cellApps="drivers", appPrefix="org.onosproject.",
                   mininetIp="", extraApply=None, applyArgs=None,
                   extraClean=None, cleanArgs=None, skipPack=False, installMax=False,
                   atomixClusterSize=None, useSSH=True, killRemoveMax=True, stopAtomix=False,
                   stopOnos=False, installParallel=True, cellApply=True,
                   includeCaseDesc=True, restartCluster=True ):
        """
        Description:
            Initial ONOS setting up of the tests. It will also verify the result of each steps.
            The procedures will be:
                killing onos
                creating ( optional ) /applying cell
                removing raft logs ( optional )
                uninstalling onos
                extra procedure to be applied( optional )
                building onos
                installing onos
                extra cleanup to be applied ( optional )
                setting up ssh to the onos
                checking the onos service
                starting onos
        Required Arguments:
            * cluster - the cluster driver that will be used.
        Optional Arguments:
            * hasMultiNodeRounds - True if the test is testing different set of nodes
            * startOnos - True if wish to start onos.
            * newCell - True for making a new cell and False for not making it.
            * cellName - Name of the cell that will be used.
            * cellApps - The cell apps string. Will be overwritten by main.apps if it exists
            * appPrefix - Prefix of app names. Will use "org.onosproject." by default
            * mininetIp - Mininet IP address.
            * extraApply - Function( s ) that will be called before building ONOS. Default to None.
            * applyArgs - argument of the functon( s ) of the extraApply. Should be in list.
            * extraClean - Function( s ) that will be called after building ONOS. Defaults to None.
            * cleanArgs - argument of the functon( s ) of the extraClean. Should be in list.
            * skipPack - True if wish to skip some packing.
            * installMax - True if wish to install onos max number of nodes
                False if wish to install onos of running nodes only
            * atomixClusterSize - The number of Atomix nodes in the cluster.
                Defaults to None which will be the number of OC# nodes in the cell
            * useSSH - True for using ssh when creating a cell
            * killRemoveMax - True for removing/killing max number of nodes. False for
                removing/killing running nodes only.
            * stopAtomix - True if wish to stop atomix before killing it.
            * stopOnos - True if wish to stop onos before killing it.
            * restartCluster - True if wish to kill and restart atomix and onos clusters
        Returns:
            Returns main.TRUE if it everything successfully proceeded.
        """
        self.setNumCtrls( hasMultiNodeRounds )
        if includeCaseDesc:
            main.case( "Starting up " + str( cluster.numCtrls ) +
                       " node(s) ONOS cluster" )
            main.caseExplanation = "Set up ONOS with " + str( cluster.numCtrls ) + \
                                   " node(s) ONOS cluster"

        main.log.info( "ONOS cluster size = " + str( cluster.numCtrls ) )
        cellResult = main.TRUE
        if cellApply:
            try:
                apps = main.apps
            except ( NameError, AttributeError ):
                apps = cellApps
            main.log.debug( "Apps: " + str( apps ) )
            tempOnosIp = []
            for ctrl in cluster.runningNodes:
                tempOnosIp.append( ctrl.ipAddress )
            if mininetIp == "":
                mininetIp = "localhost"
                for key, value in main.componentDictionary.items():
                    if value['type'] in ['MininetCliDriver', 'RemoteMininetDriver'] and hasattr( main, key ):
                        mininetIp = getattr( main, key ).ip_address
                        break
            cellResult = self.createApplyCell( cluster, newCell,
                                               cellName, apps,
                                               mininetIp, useSSH,
                                               tempOnosIp, installMax,
                                               atomixClusterSize )

        if restartCluster:
            atomixKillResult = self.killingAllAtomix( cluster, killRemoveMax, stopAtomix )
            onosKillResult = self.killingAllOnos( cluster, killRemoveMax, stopOnos )
            killResult = atomixKillResult and onosKillResult
        else:
            killResult = main.TRUE

        if restartCluster:
            atomixUninstallResult = self.uninstallAtomix( cluster, killRemoveMax )
            onosUninstallResult = self.uninstallOnos( cluster, killRemoveMax )
            uninstallResult = atomixUninstallResult and onosUninstallResult
            self.processList( extraApply, applyArgs )

            packageResult = main.TRUE
            if not skipPack:
                packageResult = self.buildOnos(cluster)

            atomixInstallResult = self.installAtomix( cluster, installParallel )
            onosInstallResult = self.installOnos( cluster, installMax, installParallel )
            installResult = atomixInstallResult and onosInstallResult

            self.processList( extraClean, cleanArgs )
            secureSshResult = self.setupSsh( cluster )
        else:
            packageResult = main.TRUE
            uninstallResult = main.TRUE
            installResult = main.TRUE
            secureSshResult = main.TRUE

        onosServiceResult = self.checkOnosService( cluster )

        onosCliResult = main.TRUE
        if startOnos:
            onosCliResult = self.startOnosClis( cluster )

        onosNodesResult = self.checkOnosNodes( cluster )

        onosAppsResult = main.TRUE
        if cellApply:
            if apps:
                apps = apps.split( ',' )
                apps = [ appPrefix + app for app in apps ]
                onosAppsResult = self.checkOnosApps( cluster, apps )
            else:
                main.log.warn( "No apps were specified to be checked after startup" )

        return killResult and cellResult and packageResult and uninstallResult and \
               installResult and secureSshResult and onosServiceResult and onosCliResult and \
               onosNodesResult and onosAppsResult
