#!/usr/bin/env python

"""
onos.py: A basic (?) ONOS Controller() subclass for Mininet

We implement the following classes:

ONOSController: a custom Controller() subclass to start ONOS
OVSSwitchONOS: a custom OVSSwitch() switch that connects to multiple controllers.

We use single Zookeeper and Cassandra instances for now.

As a custom file, exports:

--controller onos
--switch ovso

Usage:

$ sudo ./onos.py

This will start up a simple 2-host, 2 ONOS network

$ sudo mn --custom onos.py --controller onos,2 --switch ovso
"""

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

# This should be cleaned up to avoid interfering with mn
from shutil import copyfile
from os import environ
from functools import partial
import time
from sys import argv

class ONOS( Controller ):
    "Custom controller class for ONOS"

    # Directories and configuration templates
    home = environ[ 'HOME' ]
    onosDir = home + "/ONOS"
    zookeeperDir = home + "/zookeeper-3.4.5"
    dirBase = '/tmp'
    logDir = dirBase + '/onos-%s.logs'
    # cassDir = dirBase + '/onos-%s.cassandra'
    configFile = dirBase + '/onos-%s.properties'
    logbackFile = dirBase + '/onos-%s.logback.xml'

    # Base ONOS modules
    baseModules = (
        'net.floodlightcontroller.core.FloodlightProvider',
        'net.floodlightcontroller.threadpool.ThreadPool',
        'net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher',
        'net.floodlightcontroller.ui.web.StaticWebRoutable',
        'net.onrc.onos.datagrid.HazelcastDatagrid',
        'net.onrc.onos.ofcontroller.flowmanager.FlowManager',
        'net.onrc.onos.ofcontroller.flowprogrammer.FlowProgrammer',
        'net.onrc.onos.ofcontroller.topology.TopologyManager',
        'net.onrc.onos.registry.controller.ZookeeperRegistry'
    )

    # Additions for reactive forwarding
    reactiveModules = (
            'net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager',
            'net.onrc.onos.ofcontroller.core.config.DefaultConfiguration',
            'net.onrc.onos.ofcontroller.forwarding.Forwarding'
    )

    # Module parameters
    ofbase = 6633
    restbase = 8080
    jmxbase = 7189

    fc = 'net.floodlightcontroller.'

    perNodeConfigBase = {
        fc + 'core.FloodlightProvider.openflowport': ofbase,
        fc + 'restserver.RestApiServer.port': restbase,
        fc + 'core.FloodlightProvider.controllerid': 0
    }

    staticConfig = {
        'net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf':
            '/tmp/cassandra.titan',
        'net.onrc.onos.datagrid.HazelcastDatagrid.datagridConfig':
            onosDir + '/conf/hazelcast.xml',
        'net.floodlightcontroller.core.FloodlightProvider.workerthreads': 16,
        'net.floodlightcontroller.forwarding.Forwarding.idletimeout': 5,
        'net.floodlightcontroller.forwarding.Forwarding.hardtimeout': 0
    }

    proctag = 'mn-onos-id'

    # For maven debugging
    # mvn = 'mvn -o -e -X'

    def __init__( self, name, n=1, reactive=True, runAsRoot=False, **params):
        """n: number of ONOS instances to run (1)
           reactive: run in reactive mode (True)
           runAsRoot: run ONOS as root (False)"""
        self.check()
        self.count = n
        self.reactive = reactive
        self.runAsRoot = runAsRoot
        self.ids = range( 0, self.count )
        Controller.__init__( self, name, **params )
        # We don't need to run as root, and it can interfere
        # with starting Zookeeper manually
        self.user = None
        if not self.runAsRoot:
            try:
                self.user = quietRun( 'who am i' ).split()[ 0 ]
                self.sendCmd( 'su', self.user )
                self.waiting = False
            except:
                warn( '__init__: failed to drop privileges\n' )
        # Need to run commands from ONOS dir
        self.cmd( 'cd', self.onosDir )
        self.cmd( 'export PATH=$PATH:%s' % self.onosDir )
        if hasattr( self, 'mvn' ):
            self.cmd( 'export MVN="%s"' % self.mvn )

    def check( self ):
        "Check for ONOS prerequisites"
        if not quietRun( 'which java' ):
                raise Exception( 'java not found -'
                                 ' make sure it is installed and in $PATH' )
        if not quietRun( 'which mvn' ):
                raise Exception( 'Maven (mvn) not found -'
                                ' make sure it is installed and in $PATH' )


    def waitNetstat( self, pid ):
        """Wait for pid to show up in netstat
           We assume that once a process is listening on some
           port, it is ready to go!"""
        while True:
            output = self.cmd( 'sudo netstat -natp | grep %s/' % pid )
            if output:
                return output
            info( '.' )
            time.sleep( 1 )

    def waitStart( self, procname, pattern ):
        "Wait for at least one of procname to show up in netstat"
        info( '* Waiting for %s startup' % procname )
        result = self.cmd( 'pgrep -f %s' % pattern ).split()[ 0 ]
        pid = int( result )
        output = self.waitNetstat( pid )
        info( '\n* %s process %d is listening\n' % ( procname, pid ) )
        info( output )

    def startCassandra( self ):
        "Start Cassandra"
        self.cmd( 'start-cassandra.sh start' )
        self.waitStart( 'Cassandra', 'apache-cassandra' )
        status = self.cmd( 'start-cassandra.sh status' )
        if 'running' not in status:
            raise Exception( 'Cassandra startup failed: ' + status )

    def stopCassandra( self ):
        "Stop Cassandra"
        self.cmd( 'start-cassandra.sh stop' )

    def startZookeeper( self, initcfg=True ):
        "Start Zookeeper"
        # Reinitialize configuration file
        if initcfg:
            cfg = self.zookeeperDir + '/conf/zoo.cfg'
            template = self.zookeeperDir + '/conf/zoo_sample.cfg'
            copyfile( template, cfg )
        self.cmd( 'start-zk.sh restart' )
        self.waitStart( 'Zookeeper', 'zookeeper' )
        status = self.cmd( 'start-zk.sh status' )
        if 'Error' in status:
            raise Exception( 'Zookeeper startup failed: ' + status )

    def stopZookeeper( self ):
        "Stop Zookeeper"
        self.cmd( 'start-zk.sh stop' )

    def genProperties( self, id, path='/tmp' ):
        "Generate ONOS properties file"
        filename = path + '/onos-%s.properties' % id
        with open( filename, 'w' ) as f:
            # Write modules list
            modules = list( self.baseModules )
            if self.reactive:
                modules += list( self.reactiveModules )
            f.write( 'floodlight.modules = %s\n' %
                     ',\\\n'.join( modules ) )
            # Write other parameters
            for var, val in self.perNodeConfigBase.iteritems():
                if type( val ) is int:
                    val += id
                f.write( '%s = %s\n' % ( var, val ) )
            for var, val in self.staticConfig.iteritems():
                f.write( '%s = %s\n' % ( var, val ) )
        return filename

    def setVars( self, id, propsFile ):
        """Set and return environment vars
           id: ONOS instance number
           propsFile: properties file name"""
        # ONOS directories and files
        logdir = self.logDir % id
        # cassdir = self.cassDir % id
        logback = self.logbackFile % id
        jmxport = self.jmxbase + id
        self.cmd( 'mkdir -p', logdir ) # , cassdir
        self.cmd( 'export ONOS_LOGDIR="%s"' % logdir )
        self.cmd( 'export ZOO_LOG_DIR="%s"' % logdir )
        # self.cmd( 'export CASS_DIR="%s"' % cassdir )
        self.cmd( 'export ONOS_LOGBACK="%s"' % logback )
        self.cmd( 'export JMX_PORT=%s' % jmxport )
        self.cmd( 'export JVM_OPTS="-D%s=%s"' % (
            self.proctag, id ) )
        self.cmd( 'export ONOS_PROPS="%s"' % propsFile )

    def startONOS( self, id ):
        """Start ONOS
           id: new instance number"""
        start = time.time()
        self.stopONOS( id )
        propsFile = self.genProperties( id )
        self.setVars( id, propsFile )
        self.cmdPrint( 'start-onos.sh startnokill' )
        # start-onos.sh waits for ONOS startup
        elapsed = time.time() - start
        info( '* ONOS %s started in %.2f seconds\n' % ( id, elapsed ) )

    def stopONOS( self, id ):
        """Shut down ONOS
           id: identifier for instance"""
        pid = self.cmd( "jps -v | grep %s=%s | awk '{print $1}'" %
            ( self.proctag, id ) ).strip()
        if pid:
            self.cmdPrint( 'kill', pid )

    def start( self, *args ):
        "Start ONOS instances"
        info( '* Starting Cassandra\n' )
        self.startCassandra()
        info( '* Starting Zookeeper\n' )
        self.startZookeeper()
        for id in self.ids:
            info( '* Starting ONOS %s\n' % id )
            self.startONOS( id )

    def stop( self, *args ):
        "Stop ONOS instances"
        for id in self.ids:
            info( '* Stopping ONOS %s\n' % id )
            self.stopONOS( id )
        info( '* Stopping Zookeeper\n' )
        self.stopZookeeper()
        info( '* Stopping Cassandra\n' )
        self.stopCassandra()

    def clist( self ):
        "Return list of controller specifiers (proto:ip:port)"
        return [ 'tcp:127.0.0.1:%s' % ( self.ofbase + id )
            for id in range( 0, self.count ) ]


class OVSSwitchONOS( OVSSwitch ):
    "OVS switch which connects to multiple controllers"
    def start( self, controllers ):
        OVSSwitch.start( self, controllers )
        assert len( controllers ) == 1
        c0 = controllers[ 0 ]
        assert type( c0 ) == ONOS
        clist = ','.join( c0.clist() )
        self.cmd( 'ovs-vsctl set-controller', self, clist)
        # Reconnect quickly to controllers (1s vs. 15s max_backoff)
        for uuid in self.controllerUUIDs():
            if uuid.count( '-' ) != 4:
                # Doesn't look like a UUID
                continue
            uuid = uuid.strip()
            self.cmd( 'ovs-vsctl set Controller', uuid,
                      'max_backoff=1000' )


def waitConnected( switches ):
    "Wait until all switches connect to controllers"
    start = time.time()
    info( '* Waiting for switches to connect...\n' )
    for s in switches:
        info( s )
        while not s.connected():
            info( '.' )
            time.sleep( 1 )
        info( ' ' )
    elapsed = time.time() - start
    info( '\n* Connected in %.2f seconds\n' % elapsed )


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


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