# Path: orangengine/utils.py
# def enum(*sequential, **named):
#     enums = dict(zip(sequential, range(len(sequential))), **named)
#     reverse = dict((value, key) for key, value in enums.iteritems())
#     enums['reverse_mapping'] = reverse
#     return type('Enum', (), enums)
# 
# class bidict(dict):
#     """Bidirectional dictionary for two-way lookups
# 
#     Thanks to @Basj
#     http://stackoverflow.com/questions/3318625/efficient-bidirectional-hash-table-in-python
# 
#     Extended to allow blind access to the inverse dict by way of __getitem__
#     """
#     def __init__(self, *args, **kwargs):
#         super(bidict, self).__init__(*args, **kwargs)
#         self.inverse = {}
#         for key, value in self.iteritems():
#             self.inverse.setdefault(value, []).append(key)
# 
#     def __setitem__(self, key, value):
#         super(bidict, self).__setitem__(key, value)
#         self.inverse.setdefault(value, []).append(key)
# 
#     def __delitem__(self, key):
#         self.inverse.setdefault(self[key], []).remove(key)
#         if self[key] in self.inverse and not self.inverse[self[key]]:
#             del self.inverse[self[key]]
#         super(bidict, self).__delitem__(key)
# 
#     def __getitem__(self, item):
#         try:
#             value = super(bidict, self).__getitem__(item)
#         except KeyError:
#             value = self.inverse[item]
#             if value and len(value) == 1:
#                 value = value[0]
#         return value
# 
# Path: orangengine/models/base/baseservice.py
# class BaseService(BaseObject):
# 
#     def __init__(self, name, protocol=None, port=None):
#         """init a service"""
# 
#         self.name = name
#         self.protocol = protocol if protocol else "unknown"
#         if port is not None and '-' in port:
#             start = port.split('-')[0]
#             stop = port.split('-')[1]
#             if start != stop:
#                 self.port = BasePortRange(start, stop)
#             else:
#                 self.port = start
#         else:
#             self.port = port if port else "unknown"
#         self.terms = list()
# 
#     def add_term(self, term):
#         """append a service term"""
# 
#         self.terms.append(term)
# 
#     def __getattr__(self, item):
# 
#         if item == 'value':
#             if len(self.terms) > 0:
#                 return [t.value for t in self.terms]
#             elif isinstance(self.port, BasePortRange):
#                 return self.protocol, self.port.value
#             else:
#                 return self.protocol, self.port
#         else:
#             raise AttributeError
# 
#     def table_value(self, with_names):
#         if with_names:
#             return self.name + " - " + self.value[0] + "/" + self.value[1]
#         else:
#             if isinstance(self.value, list):
#                 return "\n".join([s[0] + "/" + s[1] for s in self.value])
#             return self.value[0] + "/" + self.value[1]
# 
#     @classmethod
#     def from_criteria(cls, criteria):
#         """Create an instance from the provided criteria
#         """
# 
#         return cls(criteria['name'], criteria['protocol'], criteria['port'])
# 
#     def serialize(self):
#         """Searialize self to a json acceptable data structure
#         """
# 
#         terms = []
#         if self.terms:
#             for term in self.terms:
#                 terms.append(term.serialize())
# 
#         if isinstance(self.port, BasePortRange):
#             port = self.port.serialize()
#         else:
#             port = self.port
# 
#         return {
#             'name': self.name,
#             'terms': terms,
#             'protocol': self.protocol,
#             'port': port,
#         }
# 
# Path: orangengine/models/base/baseobject.py
# class BaseObject(object):
#     """Base class for all (most) objects. This class should almost never be
#     instantiated directly. It contains a few methods that are the available to
#     all sub classes.
#     """
# 
#     def serialize(self):
#         raise NotImplementedError()
# 
#     def to_json(self):
#         """Return a json dump of self returned from self.serialize()
#         """
#         return json.dumps(self.serialize())


from orangengine.utils import enum, bidict
from orangengine.models.base import BaseService
from orangengine.models.base import BaseObject
# -*- coding: utf-8 -*-


class PaloAltoApplication(BaseObject):
    """Palo Alto Appliciation
    """

    IdentTypes = enum('PORT', 'PROTOCOL', 'ICMP', 'ICMP6')
    IdentTypeMap = bidict({
        IdentTypes.PORT: 'port',
        IdentTypes.PROTOCOL: 'ident-by-ip-protocol',
        IdentTypes.ICMP: 'ident-by-icmp-type',
        IdentTypes.ICMP6: 'ident-by-icmp6-type',
        None: None,
    })


# Path: orangengine/utils.py
# def enum(*sequential, **named):
#     enums = dict(zip(sequential, range(len(sequential))), **named)
#     reverse = dict((value, key) for key, value in enums.iteritems())
#     enums['reverse_mapping'] = reverse
#     return type('Enum', (), enums)
# 
# class bidict(dict):
#     """Bidirectional dictionary for two-way lookups
# 
#     Thanks to @Basj
#     http://stackoverflow.com/questions/3318625/efficient-bidirectional-hash-table-in-python
# 
#     Extended to allow blind access to the inverse dict by way of __getitem__
#     """
#     def __init__(self, *args, **kwargs):
#         super(bidict, self).__init__(*args, **kwargs)
#         self.inverse = {}
#         for key, value in self.iteritems():
#             self.inverse.setdefault(value, []).append(key)
# 
#     def __setitem__(self, key, value):
#         super(bidict, self).__setitem__(key, value)
#         self.inverse.setdefault(value, []).append(key)
# 
#     def __delitem__(self, key):
#         self.inverse.setdefault(self[key], []).remove(key)
#         if self[key] in self.inverse and not self.inverse[self[key]]:
#             del self.inverse[self[key]]
#         super(bidict, self).__delitem__(key)
# 
#     def __getitem__(self, item):
#         try:
#             value = super(bidict, self).__getitem__(item)
#         except KeyError:
#             value = self.inverse[item]
#             if value and len(value) == 1:
#                 value = value[0]
#         return value
# 
# Path: orangengine/models/base/baseservice.py
# class BaseService(BaseObject):
# 
#     def __init__(self, name, protocol=None, port=None):
#         """init a service"""
# 
#         self.name = name
#         self.protocol = protocol if protocol else "unknown"
#         if port is not None and '-' in port:
#             start = port.split('-')[0]
#             stop = port.split('-')[1]
#             if start != stop:
#                 self.port = BasePortRange(start, stop)
#             else:
#                 self.port = start
#         else:
#             self.port = port if port else "unknown"
#         self.terms = list()
# 
#     def add_term(self, term):
#         """append a service term"""
# 
#         self.terms.append(term)
# 
#     def __getattr__(self, item):
# 
#         if item == 'value':
#             if len(self.terms) > 0:
#                 return [t.value for t in self.terms]
#             elif isinstance(self.port, BasePortRange):
#                 return self.protocol, self.port.value
#             else:
#                 return self.protocol, self.port
#         else:
#             raise AttributeError
# 
#     def table_value(self, with_names):
#         if with_names:
#             return self.name + " - " + self.value[0] + "/" + self.value[1]
#         else:
#             if isinstance(self.value, list):
#                 return "\n".join([s[0] + "/" + s[1] for s in self.value])
#             return self.value[0] + "/" + self.value[1]
# 
#     @classmethod
#     def from_criteria(cls, criteria):
#         """Create an instance from the provided criteria
#         """
# 
#         return cls(criteria['name'], criteria['protocol'], criteria['port'])
# 
#     def serialize(self):
#         """Searialize self to a json acceptable data structure
#         """
# 
#         terms = []
#         if self.terms:
#             for term in self.terms:
#                 terms.append(term.serialize())
# 
#         if isinstance(self.port, BasePortRange):
#             port = self.port.serialize()
#         else:
#             port = self.port
# 
#         return {
#             'name': self.name,
#             'terms': terms,
#             'protocol': self.protocol,
#             'port': port,
#         }
# 
# Path: orangengine/models/base/baseobject.py
# class BaseObject(object):
#     """Base class for all (most) objects. This class should almost never be
#     instantiated directly. It contains a few methods that are the available to
#     all sub classes.
#     """
# 
#     def serialize(self):
#         raise NotImplementedError()
# 
#     def to_json(self):
#         """Return a json dump of self returned from self.serialize()
#         """
#         return json.dumps(self.serialize())


# Path: orangengine/models/paloalto/applciation.py
from orangengine.utils import enum, bidict
from orangengine.models.base import BaseService
from orangengine.models.base import BaseObject

# -*- coding: utf-8 -*-


class PaloAltoApplication(BaseObject):
    """Palo Alto Appliciation
    """

    IdentTypes = enum('PORT', 'PROTOCOL', 'ICMP', 'ICMP6')
    IdentTypeMap = bidict({
        IdentTypes.PORT: 'port',
        IdentTypes.PROTOCOL: 'ident-by-ip-protocol',
        IdentTypes.ICMP: 'ident-by-icmp-type',
        IdentTypes.ICMP6: 'ident-by-icmp6-type',
        None: None,
    })


    WellKnownServiceMap = bidict({