#!/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 (6633)
        #self.protocol = protocol ('tcp')
        #self.checkListening()

        self.onosDir = onosDir
        self.karafDir = onosDir + 'apache-karaf-3.0.2/'
        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.0.0-SNAPSHOT/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( self.instanceDir + 'bin/start' )
        #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 ):
        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>' + '192.168.123.*' + '</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()
