#!/usr/bin/env python

# TODO add onos-app-fwd to features
# TODO check if service is running... i think this might already be done by mn

from mininet.node import Controller, OVSSwitch, CPULimitedHost, RemoteController
from mininet.net import Mininet
from mininet.cli import CLI
from mininet.topo import LinearTopo, Topo
from mininet.log import setLogLevel, info, warn
from mininet.util import quietRun, numCores

from shutil import copyfile
from os import environ, path
from functools import partial
import time
from sys import argv
from time import sleep
from sets import Set

class ONOS( Controller ):
    "TODO"

    onosDir = '/opt/onos/'

    def __init__( self, name, onosDir=onosDir,
                  reactive=True, features=[ 'onos-app-tvue' ],
                  **kwargs ):
        '''TODO'''

        Controller.__init__( self, name, **kwargs )
        # the following have been done for us:
        #self.ip = ip ('127.0.0.1')
        #self.port = port (6653)
        #self.protocol = protocol ('tcp')
        #self.checkListening()

        self.onosDir = onosDir
        self.karafDir = onosDir + 'apache-karaf-3.0.5/'
        self.instanceDir = self.karafDir

        # add default modules
        # TODO: consider an ordered set
        self.features = Set([ 'webconsole',
                              'onos-rest',
                              'onos-api',
                              'onos-cli',
                              'onos-openflow' ])
        self.features.update( features )
        # add reactive forwarding modules
        if reactive:
            self.features.update( ['onos-app-fwd', 
                                   'onos-app-proxyarp',
                                   'onos-app-mobility' ] )
        # add the distributed core if we are in a namespace with no trivial core
        if self.inNamespace and 'onos-core-trivial' not in self.features:
            self.features.add( 'onos-core' )
        # if there is no core, add the trivial one
        if 'onos-core' not in self.features:
            self.features.add( 'onos-core-trivial' )
        print self.features  
   
    def start( self ):
        if self.inNamespace:
            instanceOpts = ( '-furl mvn:org.onosproject/onos-features/1.6.0-rc1/xml/features '
                             '-s 8101' )
            if self.ip is not None:
                instanceOpts += (' -a %s' % self.IP() )
            self.userCmd( self.karafDir + 'bin/instance create %s %s' % ( instanceOpts, self.name ) )
            self.instanceDir = self.karafDir + 'instances/%s/' % self.name
        else:
            # we are running in the root namespace, so let's use the root instance
            # clean up the data directory
            #self.userCmd( 'rm -rf '+ self.karafDir + 'data/' )
            pass

        self.userCmd( 'rm -rf '+ self.instanceDir + 'data/' )

        # Update etc/org.apache.karaf.features.cfg
        self.updateFeatures()

        # TODO 2. Update etc/hazelcast.xml : interface lines
        #cp etc/hazelcast.xml instances/c1/etc/
        self.updateHazelcast()

        # TODO 3. Update etc/system.properties : onos.ip
        # TODO 4. Update config/cluster.json : with all nodes

        # start onos
        self.userCmd( '%sbin/instance start -d %s' % ( self.karafDir, self.name ) )
        #TODO we should wait for startup...

    def stop( self ):
        self.userCmd( self.instanceDir + 'bin/stop' )
        #if self.inNamespace:
        #    self.userCmd( self.karafDir + 'bin/instance destroy %s' % self.name )
        self.terminate()

    def updateHazelcast( self ):
        hz = '192.168.123.*'
        if self.ip is not None:
            hz = '.'.join(self.ip.split('.')[:-1]) + '.*'

        readfile = self.karafDir + 'etc/hazelcast.xml'
        writefile = self.instanceDir + 'etc/hazelcast.xml'
        with open( readfile, 'r' ) as r:
            with open( writefile, 'w' ) as w:
                for line in r.readlines():
                    if '<interface>' in line:
                        line = '<interface>' + hz + '</interface>\n'
                    w.write( line )

    def updateFeatures( self ):
        filename = self.instanceDir + 'etc/org.apache.karaf.features.cfg'
        with open( filename, 'r+' ) as f:
            lines = f.readlines()
            f.seek(0)
            f.truncate()
            for line in lines:
                #print '?', line,
                if 'featuresBoot=' in line:
                    # parse the features from the line
                    features = line.rstrip().split('=')[1].split(',')
                    # add the features to our features set
                    self.features.update( features )
                    # generate the new features line
                    line = 'featuresBoot=' + ','.join( self.features ) + '\n'
                    #print '!', line,
                f.write( line )


    @classmethod
    def isAvailable( self ):
        return quietRun( 'ls %s' % self.onosDir )

    def userCmd( self, cmd ):
        # switch to the non-root user because karaf gets upset otherwise
        # because the .m2repo is not stored with root
        cmd = 'sudo -u %s %s' % ( self.findUser(), cmd )
        return self.cmd( cmd )

    @staticmethod
    def findUser():
        "Try to return logged-in (usually non-root) user"
        try:
            # If we're running sudo
            return os.environ[ 'SUDO_USER' ]
        except:
            try:
                # Logged-in user (if we have a tty)
                return quietRun( 'who am i' ).split()[ 0 ]
            except:
                # Give up and return effective user
                return quietRun( 'whoami' )
 

class ControlNetwork( Topo ):
    "Control Network Topology"
    def __init__( self, n, dataController=ONOS, **kwargs ):
        """n: number of data network controller nodes
           dataController: class for data network controllers"""
        Topo.__init__( self, **kwargs )
        # Connect everything to a single switch
        cs0 = self.addSwitch( 'cs0' )
        # Add hosts which will serve as data network controllers
        for i in range( 1, n+1 ):
            c = self.addHost( 'c%s' % i, cls=dataController,
                              inNamespace=True )
            self.addLink( c, cs0 )
        # Connect switch to root namespace so that data network
        # switches will be able to talk to us
        root = self.addHost( 'root', inNamespace=False )
        self.addLink( root, cs0 )

class ONOSCluster( Controller ):
    # TODO
    n = 3
   
    def start( self ):
        ctopo = ControlNetwork( n=self.n, dataController=ONOS )
        self.cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None )
        self.cnet.addController( 'cc0', controller=Controller )
        self.cnet.start()

        self.ctrls = []
        for host in self.cnet.hosts:
            if isinstance( host, Controller ):
                self.ctrls.append( host )
                host.start()

    def stop( self ):
        for host in self.cnet.hosts:
            if isinstance( host, Controller ):
                host.stop()
        self.cnet.stop()
        
    def clist( self ):
        "Return list of Controller proxies for this ONOS cluster"
        print 'controllers:', self.ctrls
        return self.ctrls

class OVSSwitchONOS( OVSSwitch ):
    "OVS switch which connects to multiple controllers"
    def start( self, controllers ):
        assert len( controllers ) == 1
        c0 = controllers[ 0 ]
        assert type( c0 ) == ONOSCluster
        controllers = c0.clist()
        OVSSwitch.start( self, controllers )

controllers = { 'onos': ONOS }
switches = { 'ovso': OVSSwitchONOS }

if __name__ == '__main__':
    # Simple test for ONOS() controller class
    setLogLevel( 'info' ) #TODO info
    size = 2 if len( argv ) != 2 else int( argv[ 1 ] )
    net = Mininet( topo=LinearTopo( size ),
                   #controller=ONOS,
                   controller=partial( ONOSCluster, n=3 ), #TODO
                   switch=OVSSwitchONOS )
    net.start()
    #waitConnected( net.switches )
    CLI( net )
    net.stop()
