#!/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[ '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, 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
        devlist =  map( lambda x: x['uri'], devices )
        while True:
            response = json.load(urllib2.urlopen(url))
            devs = response.get('devices')

            # Wait for all devices to be registered. There is a chance that this is only a subgraph.
            if (len(devices) == len(devs)):

                # Wait for all devices to available
                available = True
                for d in devs:
                    if d['id'] in devlist:
                        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 config 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' ]
            # FIXME: Clean up unnecessary link/device attributes, then re-enable annotations
            linkDict['durable'] = True
            # 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 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 }
        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
