#!/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

### method, mapping dpid to LINC switchId ###
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

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

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

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]

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"] = 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

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"] = dpId('of:' + link.intf1.node.dpid)
            builtLink["nodeDpid2"] = 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

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)

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)

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)
    ### dict of containing dpids as key and corresponding LINC switchId as values ###
    dpidsToLINCSwitchId = dpids_to_ids(sysConfig)
    
    ### 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('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('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:
                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 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(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"] = getSwitchConfig(net.switches)
        topoConfigJson["linkConfig"] = 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')
        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')
        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)


    @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 shutdownOE():
        "stop the optical emulator"
        info('*** Stopping linc OE...\n')
        quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True)

    @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
