# Path: topology/sniffer/daemon.py
# class SniffingDaemon():
#     """
#     A daemon that itertes through a series of device connections
#     and gets sniffed devices.
#     """
#     def __init__(self, shared_packets, lock, connections=discover_devices):
#         """
#         :param shared_packets: a list of packets discovered by the sniffer
#         :param lock: the lock that protects the shared_packets list
#         :connections: the connections used to pool packets
#         """
#         self.packets = shared_packets
#         self.lock = lock
# 
#         # If the default argument was given, then we call discover_devices
#         if connections == discover_devices:
#             self.connections = discover_devices()
#         else:
#             self.connections = connections
# 
#     def get_new_packets(self, filter_mask="10.1.1.1/32"):
#         """
#         Updates the list of shared packets via new packests provided through
#         scans.
# 
#         For the moment we ask each device for a packet. If this proves to
#         be a problem, we need to group the reads.
# 
#         :param filter_mask: the filter mask of form `IP/bits` used to filter
#             the GOOD packets
#         :return: returns nothing
#         """
#         new_packets = []
#         for connection in self.connections:
#             try:
#                 (header, packet) = connection.next()
#                 packet = parse_packet(packet)
#                 packet = filter_packet(packet, filter_mask)
#                 if packet is not None:
#                     new_packets.append(packet)
#                     logger.debug(packet)
#             except Exception as e:
#                 # Non-eth packets received
#                 pass
# 
#         self.lock.acquire()
# 
#         for packet in new_packets:
#             self.packets.append(packet)
# 
#         self.lock.release()
# 
#     def run(self, filter_mask="10.1.1.1/32"):
#         while True:
#             self.get_new_packets(filter_mask)
# 
# Path: topology/sniffer/devices.py
# def open_connection(device_name):
#     logger.info("Openning connection with {}.".format(device_name))
#     return [pcapy.open_live(device_name, 65536 , True , 100)]
# 
# Path: service/components.py
# class Component():
#     __metaclass__ = abc.ABCMeta
#     """
#     A component class that receives JSON requests and returns stringyfied jsons.
# 
#     To implement a new component, extend this class.
#     """
# 
#     @abc.abstractmethod
#     def process(self, json):
#         pass
# 
#     def receive_post(self):
#         if request.method == "POST":
#             req = request.get_json()
#             output = self.process(req)
#             return str(output)
# 
#     def receive_get(self):
#         if request.method == "GET":
#             output = self.process("")
#             return str(output)
# 
# Path: service/server.py
# class Server():
#     """
#     A server builder class.
# 
#     Each server is extendable via adding restful components.
#     The underlying server is Flask.
# 
#     e.g.
#       Server("test_server", "30020")
#         .add_component_get("/get_route", get_component)
#         .add_component_post("/post_route", post_component)
#         .run()
#     """
#     def __init__(self, name, port):
#         self.app = Flask(name)
#         self.name = name
#         self.port = port
#         self.components = []
# 
#     def add_component_post(self, route, component):
#         self.components.append(component)
# 
#         def binder():
#             def binded():
#                 return component.receive_post()
#             binded.__name__ = self.name + route.replace("/", "_")
# 
#             return binded
# 
#         self.app.route(route, methods=['POST'])(binder())
#         return self
# 
#     def add_component_get(self, route, component):
#         self.components.append(component)
# 
#         def binder():
#             def binded():
#                 return component.receive_get()
#             binded.__name__ = self.name + route.replace("/", "_")
# 
#             return binded
# 
#         self.app.route(route, methods=['GET'])(binder())
#         return self
# 
#     def run(self):
#         self.app.run(host='0.0.0.0', port=int(self.port))
# 
# Path: service/server.py
# class Server():
#     def __init__(self, name, port):
#     def add_component_post(self, route, component):
#         def binder():
#             def binded():
#     def add_component_get(self, route, component):
#         def binder():
#             def binded():
#     def run(self):


import os
import sys
import time
import threading
from threading import Lock
from topology.sniffer.daemon import SniffingDaemon
from topology.sniffer.devices import open_connection
from service.components import Component
from service.server import Server
from service.server import config
        """
        :return: returns a list of packets as a dictionary
        """
        self.lock.acquire()

        packets = self.shared_packets[:]
        self.shared_packets[:] = []

        self.lock.release()
        return packets

class SniffingService():
    """
    Wrapper over:
      - the server with a PacketExporter component
      - the shared_list of packets and the shared_lock

    Shares the `shared_list` of packets with the sniffing daemon.
    """
    def __init__(self, device):
        shared_lock = Lock()
        shared_list = []

        self.server = Server("sniffer", config["sniffer"])
        self.server.add_component_get("/newpackets",
            PacketExporter(shared_list, shared_lock))

        if device is None:
            self.daemon = SniffingDaemon(shared_list, shared_lock)
        else:

# Path: topology/sniffer/daemon.py
# class SniffingDaemon():
#     """
#     A daemon that itertes through a series of device connections
#     and gets sniffed devices.
#     """
#     def __init__(self, shared_packets, lock, connections=discover_devices):
#         """
#         :param shared_packets: a list of packets discovered by the sniffer
#         :param lock: the lock that protects the shared_packets list
#         :connections: the connections used to pool packets
#         """
#         self.packets = shared_packets
#         self.lock = lock
# 
#         # If the default argument was given, then we call discover_devices
#         if connections == discover_devices:
#             self.connections = discover_devices()
#         else:
#             self.connections = connections
# 
#     def get_new_packets(self, filter_mask="10.1.1.1/32"):
#         """
#         Updates the list of shared packets via new packests provided through
#         scans.
# 
#         For the moment we ask each device for a packet. If this proves to
#         be a problem, we need to group the reads.
# 
#         :param filter_mask: the filter mask of form `IP/bits` used to filter
#             the GOOD packets
#         :return: returns nothing
#         """
#         new_packets = []
#         for connection in self.connections:
#             try:
#                 (header, packet) = connection.next()
#                 packet = parse_packet(packet)
#                 packet = filter_packet(packet, filter_mask)
#                 if packet is not None:
#                     new_packets.append(packet)
#                     logger.debug(packet)
#             except Exception as e:
#                 # Non-eth packets received
#                 pass
# 
#         self.lock.acquire()
# 
#         for packet in new_packets:
#             self.packets.append(packet)
# 
#         self.lock.release()
# 
#     def run(self, filter_mask="10.1.1.1/32"):
#         while True:
#             self.get_new_packets(filter_mask)
# 
# Path: topology/sniffer/devices.py
# def open_connection(device_name):
#     logger.info("Openning connection with {}.".format(device_name))
#     return [pcapy.open_live(device_name, 65536 , True , 100)]
# 
# Path: service/components.py
# class Component():
#     __metaclass__ = abc.ABCMeta
#     """
#     A component class that receives JSON requests and returns stringyfied jsons.
# 
#     To implement a new component, extend this class.
#     """
# 
#     @abc.abstractmethod
#     def process(self, json):
#         pass
# 
#     def receive_post(self):
#         if request.method == "POST":
#             req = request.get_json()
#             output = self.process(req)
#             return str(output)
# 
#     def receive_get(self):
#         if request.method == "GET":
#             output = self.process("")
#             return str(output)
# 
# Path: service/server.py
# class Server():
#     """
#     A server builder class.
# 
#     Each server is extendable via adding restful components.
#     The underlying server is Flask.
# 
#     e.g.
#       Server("test_server", "30020")
#         .add_component_get("/get_route", get_component)
#         .add_component_post("/post_route", post_component)
#         .run()
#     """
#     def __init__(self, name, port):
#         self.app = Flask(name)
#         self.name = name
#         self.port = port
#         self.components = []
# 
#     def add_component_post(self, route, component):
#         self.components.append(component)
# 
#         def binder():
#             def binded():
#                 return component.receive_post()
#             binded.__name__ = self.name + route.replace("/", "_")
# 
#             return binded
# 
#         self.app.route(route, methods=['POST'])(binder())
#         return self
# 
#     def add_component_get(self, route, component):
#         self.components.append(component)
# 
#         def binder():
#             def binded():
#                 return component.receive_get()
#             binded.__name__ = self.name + route.replace("/", "_")
# 
#             return binded
# 
#         self.app.route(route, methods=['GET'])(binder())
#         return self
# 
#     def run(self):
#         self.app.run(host='0.0.0.0', port=int(self.port))
# 
# Path: service/server.py
# class Server():
#     def __init__(self, name, port):
#     def add_component_post(self, route, component):
#         def binder():
#             def binded():
#     def add_component_get(self, route, component):
#         def binder():
#             def binded():
#     def run(self):


# Path: topology/sniffer/sniffing_service.py
import os
import sys
import time
import threading
from threading import Lock
from topology.sniffer.daemon import SniffingDaemon
from topology.sniffer.devices import open_connection
from service.components import Component
from service.server import Server
from service.server import config

        """
        :return: returns a list of packets as a dictionary
        """
        self.lock.acquire()

        packets = self.shared_packets[:]
        self.shared_packets[:] = []

        self.lock.release()
        return packets

class SniffingService():
    """
    Wrapper over:
      - the server with a PacketExporter component
      - the shared_list of packets and the shared_lock

    Shares the `shared_list` of packets with the sniffing daemon.
    """
    def __init__(self, device):
        shared_lock = Lock()
        shared_list = []

        self.server = Server("sniffer", config["sniffer"])
        self.server.add_component_get("/newpackets",
            PacketExporter(shared_list, shared_lock))

        if device is None:
            self.daemon = SniffingDaemon(shared_list, shared_lock)
        else:

            self.daemon = SniffingDaemon(shared_list, shared_lock, connections=open_connection(device))