# Path: opennsa/nsa.py
# LOG_SYSTEM = 'opennsa.nsa'
# URN_UUID_PREFIX = 'urn:uuid:'
# BIDIRECTIONAL   = 'Bidirectional'
# class NSIHeader(object):
# class SecurityAttribute(object):
# class EmptyLabelSet(Exception):
# class Label(object):
# class STP(object): # Service Termination Point
# class Link(object):
# class Path(object):
# class NetworkServiceAgent(object):
# class ConnectionInfo(object):
# class Criteria(object):
# class QueryCriteria(Criteria):
# class Schedule(object):
# class Point2PointService(object):
#     def __init__(self, requester_nsa, provider_nsa, correlation_id=None, reply_to=None, security_attributes=None, connection_trace=None):
#     def _createCorrelationId(self):
#     def newCorrelationId(self):
#     def __repr__(self):
#     def __init__(self, type_, value):
#     def __repr__(self):
#     def __init__(self, type_, values=None):
#     def _parseLabelValues(self, values):
#         def createValue(value):
#     def intersect(self, other):
#     def labelValue(self):
#     def singleValue(self):
#     def enumerateValues(self):
#     def randomLabel(self):
#     def canMatch(l1, l2):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, network, port, label=None):
#     def shortName(self):
#     def baseURN(self):
#     def urn(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, src_stp, dst_stp):
#     def sourceSTP(self):
#     def destSTP(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, network_links):
#     def links(self):
#     def sourceEndpoint(self):
#     def destEndpoint(self):
#     def __str__(self):
#     def __init__(self, identity, endpoint, service_type=None):
#     def getHostPort(self):
#     def urn(self):
#     def getServiceType(self):
#     def __str__(self):
#     def __init__(self, connection_id, global_reservation_id, description, service_type, criterias, provider_nsa, requester_nsa, states, notification_id, result_id):
#     def __init__(self, revision, schedule, service_def):
#     def __init__(self, revision, schedule, service_def, children=None):
#     def __init__(self, start_time, end_time):
#     def __str__(self):
#     def __init__(self, source_stp, dest_stp, capacity, directionality=BIDIRECTIONAL, symmetric=False, ero=None, parameters=None):
# 
# Path: opennsa/plugin.py
# class BasePlugin:
# 
#     """
#     Default plugin.
# 
#     Can be used to inherint from so only relevant methods have to be defined in custom
#     plugins. Also used as default, so we don't have to check to see if a plugin exists
#     before calling.
#     """
# 
#     def init(self, cfg, ctx_factory):
#         self.cfg         = cfg
#         self.ctx_factory = ctx_factory
# 
#         self.conn_prefix = cfg[config.DOMAIN][:2].upper() + '-'
# 
# 
#     def connectionRequest(self, header, connection_id, global_reservation_id, description, criteria):
#         return defer.succeed(None)
# 
# 
#     def createConnectionId(self):
#         connection_id = self.conn_prefix + ''.join( [ random.choice(string.hexdigits[:16]) for _ in range(10) ] )
#         return defer.succeed(connection_id)
# 
# 
#     def prunePaths(self, paths):
#         return defer.succeed(paths)
# 
# 
#     def connectionCreated(self, connection):
#         return defer.succeed(None)
# 
# 
#     def connectionTerminated(self, connection):
#         return defer.succeed(None)


from zope.interface import implementer
from twisted.internet import defer
from opennsa import nsa
from opennsa.interface import IPlugin
from opennsa.plugin import BasePlugin


NETWORKS = []


def pruneLabels(path):
    """
    Some networks does not support underspecified STPs and VLAN rewrites so we help them out a bit.
    """
    for idx, link in enumerate(path):

        if any( [ n in link.src_stp.network for n in NETWORKS ] ):
            liv = link.src_stp.label.intersect(link.dst_stp.label)
            lnv = nsa.Label(liv.type_, liv.labelValue())
            link.src_stp.label = lnv
            link.dst_stp.label = lnv

            if idx > 0:
                prev_link = path[idx-1]
                prev_link.dst_stp.label = lnv

            if idx < len(path) - 1:
                next_link = path[idx+1]
                next_link.src_stp.label = lnv

    return path



@implementer(IPlugin)

# Path: opennsa/nsa.py
# LOG_SYSTEM = 'opennsa.nsa'
# URN_UUID_PREFIX = 'urn:uuid:'
# BIDIRECTIONAL   = 'Bidirectional'
# class NSIHeader(object):
# class SecurityAttribute(object):
# class EmptyLabelSet(Exception):
# class Label(object):
# class STP(object): # Service Termination Point
# class Link(object):
# class Path(object):
# class NetworkServiceAgent(object):
# class ConnectionInfo(object):
# class Criteria(object):
# class QueryCriteria(Criteria):
# class Schedule(object):
# class Point2PointService(object):
#     def __init__(self, requester_nsa, provider_nsa, correlation_id=None, reply_to=None, security_attributes=None, connection_trace=None):
#     def _createCorrelationId(self):
#     def newCorrelationId(self):
#     def __repr__(self):
#     def __init__(self, type_, value):
#     def __repr__(self):
#     def __init__(self, type_, values=None):
#     def _parseLabelValues(self, values):
#         def createValue(value):
#     def intersect(self, other):
#     def labelValue(self):
#     def singleValue(self):
#     def enumerateValues(self):
#     def randomLabel(self):
#     def canMatch(l1, l2):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, network, port, label=None):
#     def shortName(self):
#     def baseURN(self):
#     def urn(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, src_stp, dst_stp):
#     def sourceSTP(self):
#     def destSTP(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, network_links):
#     def links(self):
#     def sourceEndpoint(self):
#     def destEndpoint(self):
#     def __str__(self):
#     def __init__(self, identity, endpoint, service_type=None):
#     def getHostPort(self):
#     def urn(self):
#     def getServiceType(self):
#     def __str__(self):
#     def __init__(self, connection_id, global_reservation_id, description, service_type, criterias, provider_nsa, requester_nsa, states, notification_id, result_id):
#     def __init__(self, revision, schedule, service_def):
#     def __init__(self, revision, schedule, service_def, children=None):
#     def __init__(self, start_time, end_time):
#     def __str__(self):
#     def __init__(self, source_stp, dest_stp, capacity, directionality=BIDIRECTIONAL, symmetric=False, ero=None, parameters=None):
# 
# Path: opennsa/plugin.py
# class BasePlugin:
# 
#     """
#     Default plugin.
# 
#     Can be used to inherint from so only relevant methods have to be defined in custom
#     plugins. Also used as default, so we don't have to check to see if a plugin exists
#     before calling.
#     """
# 
#     def init(self, cfg, ctx_factory):
#         self.cfg         = cfg
#         self.ctx_factory = ctx_factory
# 
#         self.conn_prefix = cfg[config.DOMAIN][:2].upper() + '-'
# 
# 
#     def connectionRequest(self, header, connection_id, global_reservation_id, description, criteria):
#         return defer.succeed(None)
# 
# 
#     def createConnectionId(self):
#         connection_id = self.conn_prefix + ''.join( [ random.choice(string.hexdigits[:16]) for _ in range(10) ] )
#         return defer.succeed(connection_id)
# 
# 
#     def prunePaths(self, paths):
#         return defer.succeed(paths)
# 
# 
#     def connectionCreated(self, connection):
#         return defer.succeed(None)
# 
# 
#     def connectionTerminated(self, connection):
#         return defer.succeed(None)


# Path: opennsa/plugins/pruner.py
from zope.interface import implementer
from twisted.internet import defer
from opennsa import nsa
from opennsa.interface import IPlugin
from opennsa.plugin import BasePlugin



NETWORKS = []


def pruneLabels(path):
    """
    Some networks does not support underspecified STPs and VLAN rewrites so we help them out a bit.
    """
    for idx, link in enumerate(path):

        if any( [ n in link.src_stp.network for n in NETWORKS ] ):
            liv = link.src_stp.label.intersect(link.dst_stp.label)
            lnv = nsa.Label(liv.type_, liv.labelValue())
            link.src_stp.label = lnv
            link.dst_stp.label = lnv

            if idx > 0:
                prev_link = path[idx-1]
                prev_link.dst_stp.label = lnv

            if idx < len(path) - 1:
                next_link = path[idx+1]
                next_link.src_stp.label = lnv

    return path



@implementer(IPlugin)

class PrunerPlugin(BasePlugin):