#!/usr/bin/python

'''
Notes:

This file contains classes and methods useful for integrating LincOE with Mininet, 
such as startOE, stopOE, OpticalLink, and OpticalSwitch

- $ONOS_ROOT ust be set
- Need to run with sudo -E to preserve ONOS_ROOT env var
- We assume LINC-Config-Generator is named LINC-Config-Generator
- We also assume linc-oe is named linc-oe
- LINC-config-generator and linc-oe must be subdirectories of the user's
  home directory

            TODO
        -----------
    - clean up files after runtime
        - maybe save the old files in a separate directory?
    - modify script to allow startOE to run before net.start()
    - add ONOS as a controller in script

            Usage:
        ------------
    - import OpticalLink and OpticalSwitch from this module
    - import startOE and stopOE from this module
    - create topology as you would a normal topology. when 
      to an optical switch with topo.addLink, always specify cls=OpticalLink
    - when creating an optical switch, use cls=OpticalSwitch in topo.addSwitch
    - for annotations on links and switches, a dictionary must be passed in as
      the annotations argument
    - startOE must be run AFTER net.start() with net as an argument.
    - stopOE can be run at any time

I created a separate function to start lincOE to avoid subclassing Mininet.
In case anyone wants to write something that DOES subclass Mininet, I
thought I would outline how:

If we want an object that starts lincOE within the mininet class itself,
we need to add another object to Mininet that contains all of the json object
information for each switch. We would still subclass switch and link, but these
classes would basically be dummy classes that store their own json information
in the Mininet class object. We may also change the default switch class to add
it's tap interfaces from lincOE during startup. The start() method for mininet would 
grab all of the information from these switches and links, write configuration files
for lincOE using the json module, start lincOE, then run the start methodfor each
switch. The new start() method for each switch would parse through the sys.config
file that was created and find the tap interface it needs to connect to, similar 
to the findTap function that I currently use. After all of the controllers and 
switches have been started, the new Mininet start() method should also push the 
Topology configuration file to ONOS.

'''

import re
import json
import os
from time import sleep

from mininet.node import Switch, RemoteController
from mininet.topo import Topo
from mininet.util import quietRun
from mininet.net import Mininet
from mininet.log import  setLogLevel, info, error, warn
from mininet.link import Link, Intf
from mininet.cli import CLI

class OpticalSwitch( Switch ):

    def __init__( self, name, dpid=None, allowed=True,
                  switchType='ROADM', annotations={}, **params ):
        params[ 'inNamespace' ] = False
        Switch.__init__( self, name, dpid=dpid, **params )
        self.name = name
        self.annotations = annotations
        self.allowed = allowed
        self.switchType = switchType
        self.configDict = {} # dictionary that holds all of the JSON configuration data

    def start( self, *opts, **params ):
        '''Instead of starting a virtual switch, we build the JSON
           dictionary for the emulated optical switch'''
        self.configDict[ 'uri' ] = 'of:' + self.dpid
        self.configDict[ 'annotations' ] = self.annotations
        self.configDict[ 'annotations' ].setdefault( 'name', self.name )
        self.configDict[ 'hw' ] = 'OE'
        self.configDict[ 'mfr' ] = 'Linc'
        self.configDict[ 'mac' ] = 'ffffffffffff' + self.dpid[-2] + self.dpid[-1]
        self.configDict[ 'type' ] = self.switchType
        self.configDict[ 'ports' ] = []
        for port, intf in self.intfs.items():
            if intf.name == 'lo':
                continue
            else:
                self.configDict[ 'ports' ].append( intf.json() )


    def json( self ):
        "return json configuration dictionary for switch"
        return self.configDict
    
    def terminate( self ):
        pass

class OpticalLink( Link ):

    def __init__( self, node1, node2, port1=None, port2=None, allowed=True,
                  intfName1=None, intfName2=None, linkType='OPTICAL',
                  annotations={}, speed1=0, speed2=0, **params ):
        "Creates a dummy link without a virtual ethernet pair."
        self.allowed = allowed
        self.annotations = annotations
        self.linkType = linkType
        params1 = { 'speed': speed1 }
        params2 = { 'speed': speed2 }
        
        if isinstance( node1, OpticalSwitch ):
            cls1 = OpticalIntf
        else:
            cls1 = Intf
            # bad hack to stop error message from appearing when we try to set up intf in a packet switch, 
            # and there is no interface there( because we do not run makeIntfPair ). This way, we just set lo up
            intfName1 = 'lo'
        if isinstance( node2, OpticalSwitch ):
            cls2 = OpticalIntf
        else:
            cls2 = Intf
            intfName2 = 'lo'
        Link.__init__( self, node1, node2, port1=port1, port2=port2,
                       intfName1=intfName1, intfName2=intfName2, cls1=cls1,
                       cls2=cls2, params1=params1, params2=params2 )
        

    @classmethod
    def makeIntfPair( _cls, intfName1, intfName2, *args, **kwargs ):
        pass

    def json( self ):
        "build and return the json configuration dictionary for this link"
        configData = {}
        configData[ 'src' ] = ( 'of:' +  self.intf1.node.dpid + 
                                '/%s' % self.intf1.node.ports[ self.intf1 ] )
        configData[ 'dst' ] = ( 'of:' +  self.intf2.node.dpid +
                                '/%s' % self.intf2.node.ports[ self.intf2 ] )
        configData[ 'type' ] = self.linkType
        configData[ 'annotations' ] = self.annotations
        return configData

class OpticalIntf( Intf ):

    def __init__( self, name=None, node=None, speed=0, 
                  port=None, link=None, **params ):
        self.node = node
        self.speed = speed
        self.port = port
        self.link = link
        self.name = name
        node.addIntf( self, port=port )
        self.params = params
        self.ip = None

    def json( self ):
        "build and return the JSON information for this interface( not used right now )"
        configDict = {}
        configDict[ 'port' ] = self.port
        configDict[ 'speed' ] = self.speed
        configDict[ 'type' ] = 'FIBER'
        return configDict

    def config( self, *args, **kwargs ):
        "dont configure a dummy interface"
        pass

def switchJSON( switch ):
    "Returns the json configuration for a packet switch"
    configDict = {}
    configDict[ 'uri' ] = 'of:' + switch.dpid
    configDict[ 'mac' ] = quietRun( 'cat /sys/class/net/%s/address' % switch.name ).strip( '\n' ).translate( None, ':' )
    configDict[ 'hw' ] = 'PK' # FIXME what about OVS?
    configDict[ 'mfr' ] = 'Linc' # FIXME what about OVS?
    configDict[ 'type' ] = 'SWITCH' # FIXME what about OVS?
    annotations = switch.params.get( 'annotations', {} )
    annotations.setdefault( 'name', switch.name )
    configDict[ 'annotations' ] = annotations
    ports = []
    for port, intf in switch.intfs.items():
        if intf.name == 'lo':
            continue
        portDict = {}
        portDict[ 'port' ] = port
        portDict[ 'type' ] = 'FIBER' if isinstance( intf.link, OpticalLink ) else 'COPPER'
        intfList = [ intf.link.intf1, intf.link.intf2 ]
        intfList.remove( intf )
        portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance( intf.link, OpticalLink ) else 0
        ports.append( portDict )
    configDict[ 'ports' ] = ports
    return configDict


def startOE( net ):
    "Start the LINC optical emulator within a mininet instance"
    opticalJSON = {}
    linkConfig = []
    devices = []
    
    for switch in net.switches:
        if isinstance( switch, OpticalSwitch ):
            devices.append( switch.json() )
        else:
            devices.append( switchJSON( switch ) )
    opticalJSON[ 'devices' ] = devices

    for link in net.links:
        if isinstance( link, OpticalLink ) :
            linkConfig.append( link.json() )

    opticalJSON[ 'links' ] = linkConfig

    try:
        onosDir = os.environ[ 'ONOS_ROOT' ]
    except:
        onosDir = findDir( 'onos' )
        if not onosDir:
            error( 'Please set ONOS_ROOT environment variable!\n' )
            return False
        else:
            os.environ[ 'ONOS_ROOT' ] = onosDir

    info( '*** Writing Topology.json file\n' )
    with open( 'Topology.json', 'w' ) as outfile:
        json.dump( opticalJSON, outfile, indent=4, separators=(',', ': ') )

    info( '*** Converting Topology.json to linc-oe format (TopoConfig.json) file (not using oecfg) \n' )
    
    topoConfigJson = {};
    newLinkConfig = [];
    switchConfig = [];
    dpIdToName = {};

    #Iterate through all switches and convert the ROADM switches to linc-oe format
    for switch in opticalJSON["devices"]:
        if switch["type"] == "ROADM":
            builtSwitch = {}

            #set basic switch params based on annotations
            builtSwitch["allowed"] = True;
            builtSwitch["latitude"] = switch["annotations"]["latitude"];
            builtSwitch["longitude"] = switch["annotations"]["longitude"];

            nodeId = switch["uri"]

            #convert the nodeId to linc-oe format
            nodeDpid = dpId(nodeId);

            if "name" in switch:
                builtSwitch["name"] = switch["name"]
            else:
                builtSwitch["name"] = "none"

            #keep track of the name corresponding to each switch dpid
            dpIdToName[nodeDpid] = builtSwitch["name"];

            builtSwitch["nodeDpid"] = nodeDpid

            #set switch params and type
            builtSwitch["params"] = {};
            builtSwitch["params"]["numregens"] = switch["annotations"]["optical.regens"];
            builtSwitch["type"] = "Roadm"

            #append to list of switches
            switchConfig.append(builtSwitch);

    topoConfigJson["switchConfig"] = switchConfig;

    #Iterate through all optical links and convert them to linc-oe format
    for link in opticalJSON["links"]:
        if link["type"] == "OPTICAL":
            builtLink = {}

            #set basic link params for src and dst
            builtLink["allowed"] = True;
            builtLink["nodeDpid1"] = dpId(link["src"])
            builtLink["nodeDpid2"] = dpId(link["dst"])

            #set more params such as name/bandwidth/port/waves if they exist
            params = {}
            params["nodeName1"] = dpIdToName.get(builtLink["nodeDpid1"], "none")
            params["nodeName2"] = dpIdToName.get(builtLink["nodeDpid2"], "none")
            if "bandwidth" in link["annotations"]:
                params["bandwidth"] = link["annotations"]["bandwidth"]
            params["port1"] = int(link["src"].split("/")[1])
            params["port2"]  = int(link["dst"].split("/")[1])

            if "optical.waves" in link["annotations"]:
                params["numWaves"] = link["annotations"]["optical.waves"]
            builtLink["params"] = params

            #set type of link (WDM or pktOpt)
            if link["annotations"]["optical.type"] == "WDM":
                builtLink["type"] = "wdmLink"
            else:
                builtLink["type"] = "pktOptLink"

            newLinkConfig.append(builtLink);

    topoConfigJson["linkConfig"] = newLinkConfig;

    #Writing to TopoConfig.json
    with open( 'TopoConfig.json', 'w' ) as outfile:
            json.dump( topoConfigJson, outfile, indent=4, separators=(',', ': ') )

    info( '*** Creating sys.config...\n' )
    configGen = findDir( 'LINC-config-generator' )
    if not configGen:
        error( "***ERROR: Could not find LINC-config-generator in user's home directory\n" )
        return False
    output = quietRun( '%s/config_generator TopoConfig.json %s/sys.config.template %s %s'
                    % ( configGen, configGen, net.controllers[ 0 ].ip, net.controllers[ 0 ].port ), shell=True )
    if output:
        error( '***ERROR: Error creating sys.config file: %s\n' % output )
        return False

    info ('*** Setting multiple controllers in sys.config...\n' )
    searchStr = '{controllers,.*$'
    ctrlStr = ''
    for index in range(len(net.controllers)):
        ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % (index, net.controllers[index].ip, net.controllers[index].port)
    replaceStr = '{controllers,[%s]},' % ctrlStr[:-1]         # Cut off last comma
    sedCmd = 'sed -i \'s/%s/%s/\' sys.config' % (searchStr, replaceStr)
    output = quietRun( sedCmd, shell=True )

    info( '*** Copying sys.config to linc-oe directory: ', output + '\n' )
    lincDir = findDir( 'linc-oe' )
    if not lincDir:
        error( "***ERROR: Could not find linc-oe in user's home directory\n" )
        return False
    output = quietRun( 'cp -v sys.config %s/rel/linc/releases/1.0/' % lincDir, shell=True ).strip( '\n' )
    info( output + '\n' )

    info( '*** Starting linc OE...\n' )
    output = quietRun( '%s/rel/linc/bin/linc start' % lincDir, shell=True )
    if output:
        error( '***ERROR: LINC-OE: %s' % output + '\n' )
        quietRun( '%s/rel/linc/bin/linc stop' % lincDir, shell=True )
        return False
    
    info( '*** Waiting for linc-oe to start...\n' )
    waitStarted( net )
    
    info( '*** Adding cross-connect (tap) interfaces to packet switches...\n' )
    for link in net.links:
        if isinstance( link, OpticalLink ):
            if link.annotations[ 'optical.type' ] == 'cross-connect':
                for intf in [ link.intf1, link.intf2 ]:
                    if not isinstance( intf, OpticalIntf ):
                        intfList = [ intf.link.intf1, intf.link.intf2 ]
                        intfList.remove( intf )
                        intf2 = intfList[ 0 ]
                        intf.node.attach( findTap( intf2.node, intf2.node.ports[ intf2 ] ) )

    info( '*** Press ENTER to push Topology.json to onos...\n' )
    raw_input() # FIXME... we should eventually remove this
    info( '*** Pushing Topology.json to ONOS\n' )
    output = quietRun( '%s/tools/test/bin/onos-topo-cfg %s Topology.json' % ( onosDir, net.controllers[ 0 ].ip ), shell=True )
    # successful output contains the two characters '{}'
    # if there is more output than this, there is an issue
    if output.strip( '{}' ):
        warn( '***WARNING: Could not push topology file to ONOS: %s' % output )

#converts node ids to linc-oe format, with colons every two chars
def dpId(id):
    nodeDpid = ""
    id = id.split("/", 1)[0]
    for i in range(3, len(id) - 1, 2):
        nodeDpid += (id[i:(i + 2):]) + ":"
    return nodeDpid[0:(len(nodeDpid) - 1)];
        
def waitStarted( net, timeout=None ):
    "wait until all tap interfaces are available"
    tapCount = 0
    time = 0
    for link in net.links:
        if isinstance( link, OpticalLink ):
            if link.annotations[ 'optical.type' ] == 'cross-connect':
                tapCount += 1
    
    while True:
        if str( tapCount ) == quietRun( 'ip addr | grep tap | wc -l', shell=True ).strip( '\n' ):
            return True
        if timeout:
            if time >= timeout:
                error( '***ERROR: Linc OE did not start within %s seconds' % timeout )
                return False
            time += .5
        sleep( .5 )

def stopOE():
    "stop the optical emulator"
    info( '*** Stopping linc OE...\n' )
    lincDir = findDir( 'linc-oe' )
    quietRun( '%s/rel/linc/bin/linc stop' % lincDir, shell=True )

def findDir( directory ):
    "finds and returns the path of any directory in the user's home directory"
    user = findUser()
    homeDir = '/home/' + user
    Dir = quietRun( 'find %s -maxdepth 1 -name %s -type d' % ( homeDir, directory ) ).strip( '\n' )
    DirList = Dir.split( '\n' )
    if not Dir:
        return None
    elif len( DirList ) > 1 :
        warn( '***WARNING: Found multiple instances of %s; using %s\n'
                 % ( directory, DirList[ 0 ] ) )
        return DirList[ 0 ]
    else:
        return Dir

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' )


def findTap( node, port, path=None ):
    '''utility function to parse through a sys.config
       file to find tap interfaces for a switch'''
    switch=False
    portLine = ''
    intfLines = []

    if path is None:
        lincDir = findDir( 'linc-oe' )
        if not lincDir:
            error( '***ERROR: Could not find linc-oe in users home directory\n' )
            return None
        path = '%s/rel/linc/releases/1.0/sys.config' % lincDir

    with open( path ) as f:
        for line in f:
            if 'tap' in line:
                intfLines.append( line )
            if node.dpid in line.translate( None, ':' ):
                switch=True
                continue
            if switch:
                if 'switch' in line:
                    switch = False
                if 'port_no,%s}' % port in line:
                    portLine = line
                    break 

    if portLine:
        m = re.search( 'port,\d+', portLine )
        port = m.group( 0 ).split( ',' )[ 1 ]
    else:
        error( '***ERROR: Could not find any ports in sys.config\n' )
        return

    for intfLine in intfLines:
        if 'port,%s' % port in intfLine:
            return re.findall( 'tap\d+', intfLine )[ 0 ]


class MininetOE( Mininet ):
    "Mininet with Linc-OE support (starts and stops linc-oe)"

    def start( self ):
        Mininet.start( self )
        startOE( self )

    def stop( self ):
        Mininet.stop( self )
        stopOE()

    def addControllers( self, controllers ):
        i = 0
        for ctrl in controllers:
            self.addController( RemoteController( 'c%d' % i, ip=ctrl ) )


class OpticalTestTopo( Topo ):

    def build( self ):
        opticalAnn = { 'optical.waves': 80, 'optical.type': "WDM", 'durable': True }
        switchAnn = { 'bandwidth': 100000, 'optical.type': 'cross-connect', 'durable': True }
        h1 = self.addHost( 'h1' )
        h2 = self.addHost( 'h2' )
        s1 = self.addSwitch( 's1' )
        s2 = self.addSwitch( 's2' )
        O4 = self.addSwitch( 'O4', cls=OpticalSwitch )
        O5 = self.addSwitch( 'O5', cls=OpticalSwitch )
        O6 = self.addSwitch( 'O6', cls=OpticalSwitch )
        self.addLink( O4, O5, cls=OpticalLink, annotations=opticalAnn )
        self.addLink( O5, O6, cls=OpticalLink, annotations=opticalAnn )
        self.addLink( s1, O4, cls=OpticalLink, annotations=switchAnn )
        self.addLink( s2, O6, cls=OpticalLink, annotations=switchAnn )
        self.addLink( h1, s1 )
        self.addLink( h2, s2 )

if __name__ == '__main__':
    import sys
    if len( sys.argv ) >= 2:
        controllers = sys.argv[1:]
    else:
        print 'Usage: ./opticalUtils.py (<Controller IP>)+'
        print 'Using localhost...\n'
        controllers = [ '127.0.0.1' ]

    setLogLevel( 'info' )
    net = MininetOE( topo=OpticalTestTopo(), controller=None, autoSetMacs=True )
    net.addControllers( controllers )
    net.start()
    CLI( net )
    net.stop()
