#!/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, 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[ 'hw' ] = 'LINC-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())
        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-topo-cfg %s\
         Topology.json network/configuration/' % (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[ '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
            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):
        "Start the LINC optical emulator within a mininet instance"
        LINCSwitch.opticalJSON = {}
        linkConfig = []
        devices = []
        #setting up the controllers for LINCSwitch class
        LINCSwitch.controllers = net.controllers

        for switch in net.switches:
            if isinstance(switch, OpticalSwitch):
                devices.append(switch.json())
            else:
                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 = {}
        dpIdToName = {}

        topoConfigJson["switchConfig"] = LINCSwitch.getSwitchConfig(dpIdToName)
        topoConfigJson["linkConfig"] = LINCSwitch.getLinkConfig(dpIdToName)

        #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):
                if link.annotations[ 'optical.type' ] == 'cross-connect':
                    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)
        while True:
            response = json.load(urllib2.urlopen(url))
            devs = response.get('devices')

            # Wait for all devices to be registered
            if (len(devices) != len(devs)):
                continue

            # Wait for all devices to available
            available = True
            for d in devs:
                available &= d['available']
            if available:
                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-topo-cfg %s Topology.json network/configuration/ &'\
                               % (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 conifg system compatible dicts to be written as Topology.json file.
        """
        topology = {}
        links = {}
        devices = {}
        ports = {}

        for switch in LINCSwitch.opticalJSON[ 'devices' ]:
            # build device entries - keyed on uri (DPID) and config key 'basic'
            devDict = {}
            devDict[ 'driver' ] = switch[ 'hw' ]
            devDict[ 'mfr' ] = switch[ 'mfr' ]
            devDict[ 'mac' ] = switch[ 'mac' ]
            devDict[ 'type' ] = switch[ 'type' ]
            devDict.update(switch[ 'annotations' ])

            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'
        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 (dpIdToName):
        switchConfig = [];
        #Iterate through all switches and convert the ROADM switches to linc-oe format
        for switch in LINCSwitch.opticalJSON["devices"]:
            if switch.get("type", "none") == "ROADM":
                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);

                #assumed that all switches have this entry
                nodeId = switch["uri"]

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

                builtSwitch["name"] = switch.get("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"].get("optical.regens", 0);
                builtSwitch["type"] = "Roadm"

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

    @staticmethod
    def getLinkConfig (dpIdToName):
        newLinkConfig = [];
        #Iterate through all optical links and convert them to linc-oe format
        for link in LINCSwitch.opticalJSON["links"]:
            if link.get("type", "none") == "OPTICAL":
                builtLink = {}

                #set basic link params for src and dst
                builtLink["allowed"] = True;
                builtLink["nodeDpid1"] = LINCSwitch.dpId(link["src"])
                builtLink["nodeDpid2"] = LINCSwitch.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")
                
                params["port1"] = int(link["src"].split("/")[1])
                params["port2"]  = int(link["dst"].split("/")[1])

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

                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"].get("optical.type", "cross-connect") == "WDM":
                    builtLink["type"] = "wdmLink"
                else:
                    builtLink["type"] = "pktOptLink"

                newLinkConfig.append(builtLink);
        return newLinkConfig


    @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):
                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\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 tops 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 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')


    @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 }
        # self.isCrossConnect = True if self.annotations.get('optical.type') == 'cross-connect' else False
        if isinstance(node1, LINCSwitch) and isinstance(node2, LINCSwitch):
            self.isCrossConnect = False
        else:
            self.isCrossConnect = True
        if isinstance(node1, LINCSwitch):
            cls1 = LINCIntf
            if self.isCrossConnect:
                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.isCrossConnect:
                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

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
