# 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,
#         }
# 
# class BasePortRange(BaseObject):
# 
#     def __init__(self, start, stop):
#         """init a port range"""
# 
#         self.start = start
#         self.stop = stop
# 
#     def __str__(self):
#         return '{0} {1}'.format(self.start, self.stop)
# 
#     def __getattr__(self, item):
# 
#         if item == 'value':
#             return self.start + "-" + self.stop
#         else:
#             raise AttributeError
# 
#     def serialize(self):
#         """Searialize self to a json acceptable data structure
#         """
# 
#         return {
#             'start': self.start,
#             'stop': self.stop,
#         }
# 
# Path: orangengine/utils.py
# def create_element(tag, text=None, parent=None):
#     # create an ambiguous xml element
#     if parent is not None:
#         e = letree.SubElement(parent, tag)
#     else:
#         e = letree.Element(tag)
#     if text:
#         e.text = text
#     return e


from orangengine.models.base import BaseService, BasePortRange
from orangengine.utils import create_element


class JuniperSRXService(BaseService):

    def __init__(self, name, protocol=None, port=None):

        super(JuniperSRXService, self).__init__(name, protocol, port)

    def to_xml(self):
        """Map service objects to juniper SRX config tree elements
        """

        def map_destination_port(port):
            if isinstance(port, BasePortRange):
                port = port.value
            return create_element('destination-port', text=port)

        service_element = create_element('application')
        create_element('name', text=self.name, parent=service_element)
        if len(self.terms) > 0:
            # termed based service
            for term in self.terms:
                term_element = create_element('term', parent=service_element)
                term_element.append(map_destination_port(term.port))
                create_element('source-port', text='0-65535', parent=term_element)
                create_element('protocol', text=term.protocol, parent=term_element)
                create_element('name', text=term.name, parent=term_element)
        else:
            service_element.append(map_destination_port(self.port))
            create_element('source-port', text='0-65535', parent=service_element)

# 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,
#         }
# 
# class BasePortRange(BaseObject):
# 
#     def __init__(self, start, stop):
#         """init a port range"""
# 
#         self.start = start
#         self.stop = stop
# 
#     def __str__(self):
#         return '{0} {1}'.format(self.start, self.stop)
# 
#     def __getattr__(self, item):
# 
#         if item == 'value':
#             return self.start + "-" + self.stop
#         else:
#             raise AttributeError
# 
#     def serialize(self):
#         """Searialize self to a json acceptable data structure
#         """
# 
#         return {
#             'start': self.start,
#             'stop': self.stop,
#         }
# 
# Path: orangengine/utils.py
# def create_element(tag, text=None, parent=None):
#     # create an ambiguous xml element
#     if parent is not None:
#         e = letree.SubElement(parent, tag)
#     else:
#         e = letree.Element(tag)
#     if text:
#         e.text = text
#     return e


# Path: orangengine/models/juniper/service.py
from orangengine.models.base import BaseService, BasePortRange
from orangengine.utils import create_element



class JuniperSRXService(BaseService):

    def __init__(self, name, protocol=None, port=None):

        super(JuniperSRXService, self).__init__(name, protocol, port)

    def to_xml(self):
        """Map service objects to juniper SRX config tree elements
        """

        def map_destination_port(port):
            if isinstance(port, BasePortRange):
                port = port.value
            return create_element('destination-port', text=port)

        service_element = create_element('application')
        create_element('name', text=self.name, parent=service_element)
        if len(self.terms) > 0:
            # termed based service
            for term in self.terms:
                term_element = create_element('term', parent=service_element)
                term_element.append(map_destination_port(term.port))
                create_element('source-port', text='0-65535', parent=term_element)
                create_element('protocol', text=term.protocol, parent=term_element)
                create_element('name', text=term.name, parent=term_element)
        else:
            service_element.append(map_destination_port(self.port))
            create_element('source-port', text='0-65535', parent=service_element)

            create_element('protocol', text=self.protocol, parent=service_element)