#!/usr/bin/python

'''
Notes:

This file contains classes and methods useful for integrating LincOE with Mininet,
such as startOE, stopOE, LINCLink, 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 LINCLink 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=LINCLink
    - 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 sys
import re
import json
import os
from time import sleep
import urllib2

from mininet.node import Switch, OVSSwitch, 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

# Sleep time and timeout values in seconds
SLEEP_TIME = 2
TIMEOUT = 60

class OpticalSwitch(Switch):
    """
    For now, same as Switch class.
    """
    pass

class OpticalIntf(Intf):
    """
    For now,same as Intf class.
    """
    pass

class OpticalLink(Link):
    """
    For now, same as Link.
    """
    pass

class LINCSwitch(OpticalSwitch):
    """
    LINCSwitch class
    """
    # FIXME:Sometimes LINC doesn't remove pipes and on restart increase the pipe
    # number from erlang.pipe.1.* to erlang.pipe.2.*, so should read and write
    # from latest pipe files. For now we are removing all the pipes before
    # starting LINC.
    ### User Name ###
    user = os.getlogin()
    ### pipes ###
    readPipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.r".format(user)
    writePipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.w".format(user)
    ### sys.config path ###
    sysConfig = "/home/{}/linc-oe/rel/linc/releases/1.0/sys.config".format(user)
    ### method, mapping dpid to LINC switchId ###
    @staticmethod
    def dpids_to_ids(sysConfig):
        '''
        return the dict containing switch dpids as key and LINC switch id as values
        '''
        dpids_to_ids = {}
        fd = None
        try:
            with open(sysConfig, 'r', 0) as fd:
                switch_id = 1
                for line in fd:
                    dpid = re.search(r'([0-9A-Fa-f]{2}[:-]){7}([0-9A-Fa-f]{2})+', line, re.I)
                    if dpid:
                        dpids_to_ids[dpid.group().replace(':', '')] = switch_id
                        switch_id += 1
            return dpids_to_ids
        except:
            print "Error working with {}\nError: {}\n".format(sysConfig, sys.exc_info())
            fd.close()
            return None
    ### dict of containing dpids as key and corresponding LINC switchId as values ###
    dpidsToLINCSwitchId = dpids_to_ids.__func__(sysConfig)
    @staticmethod
    def findDir(directory, userName):
        "finds and returns the path of any directory in the user's home directory"
        homeDir = '/home/' + userName
        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
    ### ONOS Directory ###
    try:
        onosDir = os.environ[ 'ONOS_ROOT' ]
    except:
        onosDir = findDir('onos', user)
        if not onosDir:
            error('Please set ONOS_ROOT environment variable!\n')
        else:
            os.environ[ 'ONOS_ROOT' ] = onosDir
    ### REST USER/PASS ###
    try:
        restUser = os.environ[ 'ONOS_WEB_USER' ]
        restPass = os.environ[ 'ONOS_WEB_PASS' ]
    except:
        error('***WARNING: $ONOS_WEB_USER and $ONOS_WEB_PASS aren\'t set!\n')
        error('***WARNING: Setting (probably) sane WEB user/pass values\n')
        restUser = 'onos'
        restPass = 'rocks'
        os.environ[ 'ONOS_WEB_USER' ] = restUser
        os.environ[ 'ONOS_WEB_PASS' ] = restPass
    ### LINC-directory
    lincDir = findDir.__func__('linc-oe', user)
    if not lincDir:
        error("***ERROR: Could not find linc-oe in user's home directory\n")
    ### LINC config generator directory###
    configGen = findDir.__func__('LINC-config-generator', user)
    if not configGen:
        error("***ERROR: Could not find LINC-config-generator in user's home directory\n")
    # list of all the controllers
    controllers = None
    def __init__(self, name, dpid=None, allowed=True,
                  switchType='ROADM', topo=None, annotations={}, controller=None, **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
        self.crossConnects = []
        self.deletedCrossConnects = []
        self.controller = controller
        self.lincId = self._get_linc_id()  # use to communicate with LINC
        self.lincStarted = False

    def start(self, *opts, **params):
        '''Instead of starting a virtual switch, we build the JSON
           dictionary for the emulated optical switch'''
        # TODO:Once LINC has the ability to spawn network element dynamically
        # we need to use this method to spawn new logical LINC switch rather then
        # bulding JSON.
        # if LINC is started then we can start and stop logical switches else create JSON
        if self.lincStarted:
            return self.start_oe()
        self.configDict[ 'uri' ] = 'of:' + self.dpid
        self.configDict[ 'annotations' ] = self.annotations
        self.configDict[ 'annotations' ].setdefault('name', self.name)
        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())
        self.lincStarted = True

    def stop(self, deleteIntfs=False):
        '''
        stop the existing switch
        '''
        # TODO:Add support for deleteIntf
        self.stop_oe()

    def dpctl( self, *args ):
        "Run dpctl command: ignore for now"
        pass

    def write_to_cli(self, command):
        '''
        send command to LINC
        '''
        fd = None
        try:
            fd = open(self.writePipe, 'w', 0)
            fd.write(command)
            fd.close()
        except:
            print "Error working with {}\nError: {}\n".format(self.writePipe, sys.exc_info())
            if fd:
                fd.close()

    def read_from_cli(self):
        '''
        read the output from the LINC CLI
        '''
        response = None
        fd = None
        try:
            fd = open(self.readPipe, 'r', 0)
            fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)  # for non-blocking read
            # FIXME:Due to non-blocking read most for the time we read nothing
            response = fd.read()
            fd.close()
        except :
            # print "Error working with {}\nError: {}\n".format(self.readPipe, sys.exc_info())
            if fd:
                fd.close()
        return response

    def _get_linc_id(self):
        '''
        return the corresponding LINC switchId.
        '''
        return LINCSwitch.dpidsToLINCSwitchId.get(self.dpid)
    #--------------------------------------------------------------------------
    # LINC CLI commands
    #--------------------------------------------------------------------------
    def start_oe(self):
        '''
         existing LINC switch
        '''
        #starting Switch
        cmd = "linc:start_switch({}).\r\n".format(self.lincId)
        self.write_to_cli(cmd)
        #hanlding taps interfaces related to the switch
        crossConnectJSON = {}
        linkConfig = []
        for i in range(0,len(self.deletedCrossConnects)):
            crossConnect = self.deletedCrossConnects.pop()
            tap = None
            if isinstance(crossConnect.intf1.node, LINCSwitch):
                intf = crossConnect.intf2
                tapPort = crossConnect.intf1.port
            else:
                intf = crossConnect.intf1
                tapPort = crossConnect.intf2.port
            tap = LINCSwitch.findTap(self, tapPort)
            if tap:
                LINCSwitch.setupInts([tap])
                intf.node.attach(tap)
            self.crossConnects.append(crossConnect)
            linkConfig.append(crossConnect.json())
        #Sending crossConnect info to the ONOS.
        crossConnectJSON['links'] = linkConfig
        with open("crossConnect.json", 'w') as fd:
            json.dump(crossConnectJSON, fd, indent=4, separators=(',', ': '))
        info('*** Pushing crossConnect.json to ONOS\n')
        output = quietRun('%s/tools/test/bin/onos-netcfg %s\
         Topology.json' % (self.onosDir, self.controllers[ 0 ].ip), shell=True)

    def stop_oe(self):
        '''
        stop the existing LINC switch
        '''
        cmd = "linc:stop_switch({}).\r\n".format(self.lincId)
        self.write_to_cli(cmd)
        #handling taps if any
        for i in range(0, len(self.crossConnects)):
            crossConnect = self.crossConnects.pop()
            if isinstance(crossConnect.intf1.node, LINCSwitch):
                intf = crossConnect.intf2
                tapPort = crossConnect.intf1.port
            else:
                intf = crossConnect.intf1
                tapPort = crossConnect.intf2.port
            intf.node.detach(LINCSwitch.findTap(self, tapPort))
            self.deletedCrossConnects.append(crossConnect)

    def w_port_up(self, port):
        '''
        port_up
        '''
        cmd = "linc:port_up({},{}).\r\n".format(self.lincId, port)
        self.write_to_cli(cmd)

    def w_port_down(self, port):
        '''
        port_down
        '''
        cmd = "linc:port_down({},{}).\r\n".format(self.lincId, port)
        self.write_to_cli(cmd)

    # helper functions
    @staticmethod
    def switchJSON(switch):
        "Returns the json configuration for a packet switch"
        configDict = {}
        configDict[ 'uri' ] = 'of:' + switch.dpid
        configDict[ 'type' ] = 'SWITCH'
        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
            portType = 'COPPER'
            if isinstance(intf.link, LINCLink):
                portType = 'OCH' if intf.link.isCrossConnect() else 'OMS'
            portDict[ 'type' ] = portType
            intfList = [ intf.link.intf1, intf.link.intf2 ]
            intfList.remove(intf)
            portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance(intf.link, LINCLink) else 0
            ports.append(portDict)
        configDict[ 'ports' ] = ports
        return configDict

    @staticmethod
    def bootOE(net, domain=None):
        """
        Start the LINC optical emulator within a mininet instance

        This involves 1. converting the information stored in Linc* to configs
        for both LINC and the network config system, 2. starting Linc, 3. connecting
        cross-connects, and finally pushing the network configs to ONOS.

        Inevitably, there are times when we have OVS switches that should not be
        under the control of the controller in charge of the Linc switches. We
        hint at these by passing domain information.
        """
        LINCSwitch.opticalJSON = {}
        linkConfig = []
        devices = []
        #setting up the controllers for LINCSwitch class
        LINCSwitch.controllers = net.controllers

        for switch in net.switches:
            if domain and switch not in domain:
                continue
            if isinstance(switch, OpticalSwitch):
                devices.append(switch.json())
            elif isinstance(switch, OVSSwitch):
                devices.append(LINCSwitch.switchJSON(switch))
        LINCSwitch.opticalJSON[ 'devices' ] = devices

        for link in net.links:
            if isinstance(link, LINCLink) :
                linkConfig.append(link.json())
        LINCSwitch.opticalJSON[ 'links' ] = linkConfig

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

        info('*** Converting Topology.json to linc-oe format (TopoConfig.json) file (no oecfg) \n')

        topoConfigJson = {}

        topoConfigJson["switchConfig"] = LINCSwitch.getSwitchConfig(net.switches)
        topoConfigJson["linkConfig"] = LINCSwitch.getLinkConfig(net.links)

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

        info('*** Creating sys.config...\n')
        output = quietRun('%s/config_generator TopoConfig.json %s/sys.config.template %s %s'
                        % (LINCSwitch.configGen, LINCSwitch.configGen, LINCSwitch.controllers[ 0 ].ip, LINCSwitch.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 = '\[{"Switch.*$'
        ctrlStr = ''
        for index in range(len(LINCSwitch.controllers)):
            ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % (index, net.controllers[index].ip, net.controllers[index].port)
        replaceStr = '[%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')
        output = quietRun('cp -v sys.config %s/rel/linc/releases/1.0/' % LINCSwitch.lincDir, shell=True).strip('\n')
        info(output + '\n')

        info('*** Adding taps and bringing them up...\n')
        LINCSwitch.setupInts(LINCSwitch.getTaps())

        info('*** removing pipes if any \n')
        quietRun('rm /tmp/home/%s/linc-oe/rel/linc/*' % LINCSwitch.user, shell=True)

        info('*** Starting linc OE...\n')
        output = quietRun('%s/rel/linc/bin/linc start' % LINCSwitch.lincDir, shell=True)
        if output:
            error('***ERROR: LINC-OE: %s' % output + '\n')
            quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True)
            return False

        info('*** Waiting for linc-oe to start...\n')
        LINCSwitch.waitStarted(net)

        info('*** Adding cross-connect (tap) interfaces to packet switches...\n')
        for link in net.links:
            if isinstance(link, LINCLink) and link.isCrossConnect():
                for intf in [ link.intf1, link.intf2 ]:
                    if not isinstance(intf, LINCIntf):
                        intfList = [ intf.link.intf1, intf.link.intf2 ]
                        intfList.remove(intf)
                        intf2 = intfList[ 0 ]
                        intf.node.attach(LINCSwitch.findTap(intf2.node, intf2.node.ports[ intf2 ]))

        info('*** Waiting for all devices to be available in ONOS...\n')
        url = 'http://%s:8181/onos/v1/devices' % LINCSwitch.controllers[0].ip
        time = 0
        # Set up password authentication
        pw_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
        pw_mgr.add_password(None, url, LINCSwitch.restUser, LINCSwitch.restPass)
        handler = urllib2.HTTPBasicAuthHandler(pw_mgr)
        opener = urllib2.build_opener(handler)
        opener.open(url)
        urllib2.install_opener(opener)
        # focus on just checking the state of devices we're interested in
        # expected devices availability map
        devMap =  dict.fromkeys(map( lambda x: x['uri'], devices ), False)
        while True:
            response = json.load(urllib2.urlopen(url))
            devs = response.get('devices')

            # update availability map
            for d in devs:
                if devMap.has_key(d['id']):
                    devMap[d['id']] = d['available']

            # Check if all devices we're interested became available
            if all(devMap.viewvalues()):
                break;

            if (time >= TIMEOUT):
                error('***ERROR: ONOS did not register devices within %s seconds\n' % TIMEOUT)
                break

            time += SLEEP_TIME
            sleep(SLEEP_TIME)

        info('*** Pushing Topology.json to ONOS\n')
        for index in range(len(LINCSwitch.controllers)):
            output = quietRun('%s/tools/test/bin/onos-netcfg %s Topology.json &'\
                               % (LINCSwitch.onosDir, LINCSwitch.controllers[ index ].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\n' % output)

    #converts node ids to linc-oe format, with colons every two chars
    @staticmethod
    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:-1]

    @staticmethod
    def makeTopoJSON():
        """
        Builds ONOS network config system compatible dicts to be written as Topology.json file.
        """
        topology = {}
        links = {}
        devices = {}
        ports = {}
        BasicDevConfigKeys = ['name', 'type', 'latitude', 'longitude', 'allowed',
                              'rackAddress', 'owner', 'driver', 'manufacturer',
                              'hwVersion', 'swVersion', 'serial',
                              'managementAddress']

        for switch in LINCSwitch.opticalJSON[ 'devices' ]:
            # Build device entries - keyed on uri (DPID) and config key 'basic'
            # 'type' is necessary field, else ONOS assumes it's a SWITCH
            # Annotations hold switch name and latitude/longitude
            devDict = {}
            devDict[ 'type' ] = switch[ 'type' ]
            devDict.update({k: v for k, v in switch[ 'annotations' ].iteritems() if k in BasicDevConfigKeys})
            devSubj = switch[ 'uri' ]
            devices[ devSubj ] = { 'basic': devDict }

            # Build port entries - keyed on "uri/port" and config key 'optical'
            for port in switch[ 'ports' ]:
                portSubj = devSubj + '/' + str(port[ 'port' ])
                ports[ portSubj ] = { 'optical': port }

        # Build link entries - keyed on "uri/port-uri/port" and config key 'basic'
        # Annotations hold the 'durable' field, which is necessary as long as we don't discover optical links
        for link in LINCSwitch.opticalJSON[ 'links' ]:
            linkDict = {}
            linkDict[ 'type' ] = link[ 'type' ]
            linkDict.update(link[ 'annotations' ])
            linkSubj = link[ 'src' ] + '-' + link[ 'dst' ]
            links[ linkSubj ] = { 'basic': linkDict }

        topology[ 'links' ] = links
        topology[ 'devices' ] = devices
        topology[ 'ports' ] = ports

        return topology

    @staticmethod
    def getSwitchConfig(switches):
        switchConfig = []

        # Iterate through all switches and convert the ROADM switches to linc-oe format
        for switch in switches:
            if isinstance(switch, LINCSwitch):
                builtSwitch = {}

                # Set basic switch params based on annotations
                builtSwitch["allowed"] = True
                builtSwitch["latitude"] = switch.annotations.get("latitude", 0.0)
                builtSwitch["longitude"] = switch.annotations.get("longitude", 0.0)

                # Convert dpid to linc-oe format
                builtSwitch["name"] = switch.name
                builtSwitch["nodeDpid"] = LINCSwitch.dpId('of:' + switch.dpid)

                # Set switch params and type
                builtSwitch["params"] = {}
                builtSwitch["params"]["numregens"] = switch.annotations.get("optical.regens", 0)
                builtSwitch["type"] = "Roadm"

                switchConfig.append(builtSwitch)

        return switchConfig

    @staticmethod
    def getLinkConfig(links):
        linkConfig = []

        # Iterate through all non-edge links and convert them to linc-oe format
        for link in links:
            if isinstance(link, LINCLink):
                builtLink = {}

                # Set basic link params for src and dst
                builtLink["allowed"] = True
                builtLink["nodeDpid1"] = LINCSwitch.dpId('of:' + link.intf1.node.dpid)
                builtLink["nodeDpid2"] = LINCSwitch.dpId('of:' + link.intf2.node.dpid)

                # Set more params such as name/bandwidth/port if they exist
                params = {}
                params["nodeName1"] = link.intf1.node.name
                params["nodeName2"] = link.intf2.node.name

                params["port1"] = link.port1
                params["port2"]  = link.port2

                if "bandwidth" in link.annotations:
                    params["bandwidth"] = link.annotations["bandwidth"]

                builtLink["params"] = params

                # Set link type to WDM or packet (LINC-config-generator relies on it)
                if link.isTransportLayer():
                    builtLink["type"] = "wdmLink"
                else:
                    builtLink["type"] = "pktOptLink"

                linkConfig.append(builtLink)

        return linkConfig


    @staticmethod
    def waitStarted(net, timeout=TIMEOUT):
        "wait until all tap interfaces are available"
        tapCount = 0
        time = 0
        for link in net.links:
            if isinstance(link, LINCLink) and link.isCrossConnect():
                tapCount += 1

        while True:
            # tapCount can be less than the actual number of taps if the optical network
            # is a subgraph of a larger multidomain network.
            tapNum = int(quietRun('ip addr | grep tap | wc -l', shell=True).strip('\n'))
            if tapCount <= tapNum:
                return True
            if timeout:
                if time >= TIMEOUT:
                    error('***ERROR: LINC OE did not start within %s seconds\n' % TIMEOUT)
                    return False
                time += SLEEP_TIME
            sleep(SLEEP_TIME)

    @staticmethod
    def shutdownOE():
        "stop the optical emulator"
        info('*** Stopping linc OE...\n')
        quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True)

    @staticmethod
    def setupInts(intfs):
        '''
        add taps and bring them up.
        '''
        for i in intfs:
            quietRun('ip tuntap add dev %s mode tap' % i)
            quietRun('ip link set dev %s up' % i)
            info('*** Intf %s set\n' % i)

    @staticmethod
    def getTaps(path=None):
        '''
        return list of all the taps in sys.config
        '''
        if path is None:
            path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir
        fd = open(path, 'r', 0)
        sys_data = fd.read()
        taps = re.findall('tap\d+', sys_data)
        fd.close()
        return taps

    @staticmethod
    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:
            path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.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 ]

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

    def terminate(self):
        pass



class LINCLink(Link):
    """
    LINC link class
    """
    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
        self.port1 = port1
        self.port2 = port2
        params1 = { 'speed': speed1 }
        params2 = { 'speed': speed2 }
        if isinstance(node1, LINCSwitch) and isinstance(node2, LINCSwitch):
            self.isXC = False
        else:
            self.isXC = True
        if isinstance(node1, LINCSwitch):
            cls1 = LINCIntf
            if self.isXC:
                node1.crossConnects.append(self)
        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, LINCSwitch):
            cls2 = LINCIntf
            if self.isXC:
                node2.crossConnects.append(self)
        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

    def isCrossConnect(self):
        if isinstance(self.intf1.node, LINCSwitch) ^ isinstance(self.intf2.node, LINCSwitch):
            return True

        return False

    def isTransportLayer(self):
        if isinstance(self.intf1.node, LINCSwitch) and isinstance(self.intf2.node, LINCSwitch):
            return True

        return False

class LINCIntf(OpticalIntf):
    """
    LINC interface class
    """
    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
        portType = 'COPPER'
        if isinstance(self.link, LINCLink):
            portType = 'OCH' if self.link.isCrossConnect() else 'OMS'
        configDict[ 'type' ] = portType
        return configDict

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

    def ifconfig(self, status):
        "configure the status"
        if status == "up":
            return self.node.w_port_up(self.port)
        elif status == "down":
            return self.node.w_port_down(self.port)


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

    def start(self):
        Mininet.start(self)
        LINCSwitch.bootOE(self)

    def stop(self):
        Mininet.stop(self)
        LINCSwitch.shutdownOE()

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

if __name__ == '__main__':
    pass
