#!/usr/bin/python

"""
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/>.
"""
"""
Multiple ovsdb OVS!!

We scale up by creating multiple ovsdb instances,
each of which is shared by several OVS switches

The shell may also be shared among switch instances,
which causes switch.cmd() and switch.popen() to be
delegated to the ovsdb instance.

"""
from mininet.net import Mininet
from mininet.node import Node, OVSSwitch
from mininet.node import OVSBridge
from mininet.link import Link, OVSIntf
from mininet.topo import LinearTopo, SingleSwitchTopo
from mininet.topolib import TreeTopo
from mininet.log import setLogLevel, info
from mininet.cli import CLI
from mininet.clean import Cleanup, sh

from itertools import groupby
from operator import attrgetter


class OVSDB( Node ):

    "Namespace for an OVSDB instance"

    privateDirs = [ '/etc/openvswitch',
                    '/var/run/openvswitch',
                    '/var/log/openvswitch' ]

    # Control network
    ipBase = '172.123.123.0/24'
    cnet = None
    nat = None

    @classmethod
    def startControlNet( cls ):
        "Start control net if necessary and return it"
        cnet = cls.cnet
        if not cnet:
            info( '### Starting control network\n' )
            cnet = Mininet( ipBase=cls.ipBase )
            cswitch = cnet.addSwitch( 'ovsbr0', cls=OVSBridge )
            # Add NAT - note this can conflict with data network NAT
            info( '### Adding NAT for control and data networks'
                  ' (use --nat flush=0 for data network)\n' )
            cls.cnet = cnet
            cls.nat = cnet.addNAT( 'ovsdbnat0' )
            cnet.start()
            info( '### Control network started\n' )
        return cnet

    def stopControlNet( self ):
        info( '\n### Stopping control network\n' )
        cls = self.__class__
        cls.cnet.stop()
        info( '### Control network stopped\n' )

    def addSwitch( self, switch ):
        "Add a switch to our namespace"
        # Attach first switch to cswitch!
        self.switches.append( switch )

    def delSwitch( self, switch ):
        "Delete a switch from our namespace, and terminate if none left"
        self.switches.remove( switch )
        if not self.switches:
            self.stopOVS()

    ovsdbCount = 0

    def startOVS( self ):
        "Start new OVS instance"
        self.cmd( 'ovsdb-tool create /etc/openvswitch/conf.db' )
        self.cmd( 'ovsdb-server /etc/openvswitch/conf.db'
                  ' -vfile:emer -vfile:err -vfile:info'
                  ' --remote=punix:/var/run/openvswitch/db.sock '
                  ' --log-file=/var/log/openvswitch/ovsdb-server.log'
                  ' --pidfile=/var/run/openvswitch/ovsdb-server-mn.pid'
                  ' --no-chdir'
                  ' --detach' )

        self.cmd( 'ovs-vswitchd unix:/var/run/openvswitch/db.sock'
                  ' -vfile:emer -vfile:err -vfile:info'
                  ' --mlockall --log-file=/var/log/openvswitch/ovs-vswitchd.log'
                  ' --pidfile=/var/run/openvswitch/ovs-vswitchd-mn.pid'
                  ' --no-chdir'
                  ' --detach' )

    def stopOVS( self ):
        self.cmd( 'kill',
                  '`cat /var/run/openvswitch/ovs-vswitchd-mn.pid`',
                  '`cat /var/run/openvswitch/ovsdb-server-mn.pid`' )
        self.cmd( 'wait' )
        self.__class__.ovsdbCount -= 1
        if self.__class__.ovsdbCount <= 0:
            self.stopControlNet()

    @classmethod
    def cleanUpOVS( cls ):
        "Clean up leftover ovsdb-server/ovs-vswitchd processes"
        info( '*** Shutting down extra ovsdb-server/ovs-vswitchd processes\n' )
        sh( 'pkill -f mn.pid' )

    def self( self, *args, **kwargs ):
        "A fake constructor that sets params and returns self"
        self.params = kwargs
        return self

    def __init__( self, **kwargs ):
        cls = self.__class__
        cls.ovsdbCount += 1
        cnet = self.startControlNet()
        # Create a new ovsdb namespace
        self.switches = []
        name = 'ovsdb%d' % cls.ovsdbCount
        kwargs.update( inNamespace=True )
        kwargs.setdefault( 'privateDirs', self.privateDirs )
        super( OVSDB, self ).__init__( name, **kwargs )
        ovsdb = cnet.addHost( name, cls=self.self, **kwargs )
        link = cnet.addLink( ovsdb, cnet.switches[ 0 ] )
        cnet.switches[ 0 ].attach( link.intf2 )
        ovsdb.configDefault()
        ovsdb.setDefaultRoute( 'via %s' % self.nat.intfs[ 0 ].IP() )
        ovsdb.startOVS()


# Install cleanup callback
Cleanup.addCleanupCallback( OVSDB.cleanUpOVS )


class OVSSwitchNS( OVSSwitch ):

    "OVS Switch in shared OVSNS namespace"

    isSetup = False

    @classmethod
    def batchStartup( cls, switches ):
        result = []
        for ovsdb, switchGroup in groupby( switches, attrgetter( 'ovsdb' ) ):
            switchGroup = list( switchGroup )
            info( '(%s)' % ovsdb )
            result += OVSSwitch.batchStartup( switchGroup, run=ovsdb.cmd )
        return result

    @classmethod
    def batchShutdown( cls, switches ):
        result = []
        for ovsdb, switchGroup in groupby( switches, attrgetter( 'ovsdb' ) ):
            switchGroup = list( switchGroup )
            info( '(%s)' % ovsdb )
            for switch in switches:
                if switch.pid == ovsdb.pid:
                    switch.pid = None
                    switch.shell = None
            result += OVSSwitch.batchShutdown( switchGroup, run=ovsdb.cmd )
            for switch in switchGroup:
                switch.ovsdbFree()
        return result

    # OVSDB allocation
    groupSize = 64
    switchCount = 0
    lastOvsdb = None

    @classmethod
    def ovsdbAlloc( cls, switch ):
        "Allocate (possibly new) OVSDB instance for switch"
        if cls.switchCount % switch.groupSize == 0:
            cls.lastOvsdb = OVSDB()
        cls.switchCount += 1
        cls.lastOvsdb.addSwitch( switch )
        return cls.lastOvsdb

    def ovsdbFree( self ):
        "Deallocate OVSDB instance for switch"
        self.ovsdb.delSwitch( self )

    def startShell( self, *args, **kwargs ):
        "Start shell in shared OVSDB namespace"
        ovsdb = self.ovsdbAlloc( self )
        kwargs.update( mnopts='-da %d ' % ovsdb.pid )
        self.ns = [ 'net' ]
        self.ovsdb = ovsdb
        self._waiting = False
        if self.privateShell:
            super( OVSSwitchNS, self ).startShell( *args, **kwargs )
        else:
            # Delegate methods and initialize local vars
            attrs = ( 'cmd', 'cmdPrint', 'sendCmd', 'waitOutput',
                      'monitor', 'write', 'read',
                      'pid', 'shell', 'stdout', )
            for attr in attrs:
                setattr( self, attr, getattr( ovsdb, attr ) )
        self.defaultIntf().updateIP()

    @property
    def waiting( self ):
        "Optionally delegated to ovsdb"
        return self._waiting if self.privateShell else self.ovsdb.waiting

    @waiting.setter
    def waiting( self, value ):
        "Optionally delegated to ovsdb (read only!)"
        if self.privateShell:
            _waiting = value

    def start( self, controllers ):
        "Update controller IP addresses if necessary"
        for controller in controllers:
            if controller.IP() == '127.0.0.1' and not controller.intfs:
                controller.intfs[ 0 ] = self.ovsdb.nat.intfs[ 0 ]
        super( OVSSwitchNS, self ).start( controllers )

    def stop( self, *args, **kwargs ):
        "Stop and free OVSDB namespace if necessary"
        self.ovsdbFree()

    def terminate( self, *args, **kwargs ):
        if self.privateShell:
            super( OVSSwitchNS, self ).terminate( *args, **kwargs )
        else:
            self.pid = None
            self.shell = None

    def defaultIntf( self ):
        return self.ovsdb.defaultIntf()

    def __init__( self, *args, **kwargs ):
        """n: number of OVS instances per OVSDB
           shell: run private shell/bash process? ( False )
           If shell is shared/not private, cmd() and popen() are
           delegated to the OVSDB instance, which is different than
           regular OVSSwitch semantics!!"""
        self.groupSize = kwargs.pop( 'n', self.groupSize )
        self.privateShell = kwargs.pop( 'shell', False )
        super( OVSSwitchNS, self ).__init__( *args, **kwargs )


class OVSLinkNS( Link ):

    "OVSLink that supports OVSSwitchNS"

    def __init__( self, node1, node2, **kwargs ):
        "See Link.__init__() for options"
        self.isPatchLink = False
        if ( isinstance( node1, OVSSwitch ) and
             isinstance( node2, OVSSwitch ) and
             getattr( node1, 'ovsdb', None ) ==
             getattr( node2, 'ovsdb', None ) ):
            self.isPatchLink = True
            kwargs.update( cls1=OVSIntf, cls2=OVSIntf )
        Link.__init__( self, node1, node2, **kwargs )

switches = { 'ovsns': OVSSwitchNS, 'ovsm': OVSSwitchNS }

links = { 'ovs': OVSLinkNS }


def test():
    "Test OVSNS switch"
    setLogLevel( 'info' )
    topo = TreeTopo( depth=4, fanout=2 )
    net = Mininet( topo=topo, switch=OVSSwitchNS )
    # Add connectivity to controller which is on LAN or in root NS
    # net.addNAT().configDefault()
    net.start()
    CLI( net )
    net.stop()


if __name__ == '__main__':
    test()
