# Path: ejtp/util/compat.py

# 
# Path: ejtp/router.py
# STOPPED = 0
# THREADED = 1
# class Router(object):
#     def __init__(self, jacks=[], clients=[]):
#     def recv(self, msg):
#     def jack(self, addr):
#     def client(self, addr):
#     def kill_client(self, addr):
#     def thread_all(self):
#     def stop_all(self):
#     def run(self, level=THREADED):
#     def _loadjacks(self, jacks):
#     def _loadclients(self, clients):
#     def _loadjack(self, jack):
#     def _loadclient(self, client):
# def rtuple(obj):
# 
# Path: ejtp/client.py
# class Client(object):
#     def __init__(self, router, interface, encryptor_cache = None, make_jack = True):
#     def send(self, msg):
#     def relay(self, msg):
#     def route(self, msg):
#     def rcv_callback(self, msg, client_obj):
#     def write(self, addr, txt, wrap_sender=True):
#     def owrite(self, hoplist, msg, wrap_sender=True):
#     def owrite_json(self, hoplist, data, wrap_sender=True):
#     def write_json(self, addr, data, wrap_sender=True):
#     def wrap_sender(self, msg):
#     def identity(self):
#     def encryptor_get(self, address):
#     def encryptor_set(self, address, encryptor):
#     def sign(self, obj):
#     def sig_verify(self, obj, signer, sig):
# 
# Path: ejtp/jacks/stream.py
# class Connection(object):
#     '''
#     Represents a persistent connection to a remote host. Should be subclassed.
#     '''
#     def __init__(self, jack=None):
#         self.jack = jack
#         self._buffer = RawData()
#         self._running = False
#         self._outqueue = Queue.Queue()
#         self._thread = threading.Thread(target=self.run)
# 
#     # SUBCLASS INTERFACE ------------------------------------------------------
# 
#     @RawDataDecorator(strict=True)
#     def _send(self, frame):
#         '''
#         Subclass-provided function that sends text to the remote end.
#         '''
#         pass
# 
#     @RawDataDecorator(args=False, ret=True, strict=True)
#     def _recv(self):
#         '''
#         Subclass-provided function that returns text. Allowed to block.
#         '''
#         pass
# 
#     def run(self):
#         '''
#         Network recieve loop.
#         '''
#         pass
# 
#     # PROVIDED BY BASE CLASS --------------------------------------------------
# 
#     def start(self):
#         self._running = True
#         self._thread.start()
# 
#     def close(self):
#         self._running = False
# 
#     def send(self, frame):
#         self._send(self.wrap(frame.content))
# 
#     def recv(self, timeout=0):
#         '''
#         Retrieve from output queue without blocking. Returns None or str.
# 
#         The output queue is only used if self.jack == None.
#         '''
#         try:
#             return self._outqueue.get(timeout=timeout)
#         except Queue.Empty:
#             return None
# 
#     def wrap(self, frame):
#         '''
#         Wrap a frame for transport
#         '''
#         return RawData(format(len(frame), '0x')) + "." + frame        
# 
#     @RawDataDecorator(strict=True)
#     def inject(self, newdata):
#         '''
#         Process new data from the outside world.
#         '''
#         self._buffer += newdata
#         if RawData(".") not in self._buffer:
#             return
#         size, content = self._buffer.split('.',1)
#         size = int(size.export(), 16) # Read size as hex
#         if len(content) < size:
#             return
#         if self.jack:
#             self.jack.recv(content[:size])
#         else:
#             self._outqueue.put(content[:size])
#         self._buffer = content[size:]


from ejtp.util.compat import unittest
from persei import String, RawData
from ejtp import router, client
from ejtp.jacks.stream import Connection
import threading

class TestJacks(unittest.TestCase):

    def setUp(self):
        self.routerA = router.Router()
        self.routerB = router.Router()

    def test_udp4(self):
        self.make_test(
            ['udp4', ['127.0.0.1', 18999], 'charlie'],
            ['udp4', ['127.0.0.1', 19999], 'stacy'])

    def test_udp(self):
        self.make_test(
            ['udp', ['::1', 8999], 'charlie'],
            ['udp', ['::1', 9999], 'stacy'])

    def test_tcp4(self):
        self.make_test(
            ['tcp4', ['127.0.0.1', 18999], 'charlie'],
            ['tcp4', ['127.0.0.1', 19999], 'stacy'])

    def test_tcp(self):
        self.make_test(
            ['tcp', ['::1', 8999], 'charlie'],
            ['tcp', ['::1', 9999], 'stacy'])

    def make_test(self, ifaceA, ifaceB, messageAB='A => B', messageBA='B => A', timeout=0.5):
        clientA = client.Client(self.routerA, ifaceA)
        clientB = client.Client(self.routerB, ifaceB)

# Path: ejtp/util/compat.py

# 
# Path: ejtp/router.py
# STOPPED = 0
# THREADED = 1
# class Router(object):
#     def __init__(self, jacks=[], clients=[]):
#     def recv(self, msg):
#     def jack(self, addr):
#     def client(self, addr):
#     def kill_client(self, addr):
#     def thread_all(self):
#     def stop_all(self):
#     def run(self, level=THREADED):
#     def _loadjacks(self, jacks):
#     def _loadclients(self, clients):
#     def _loadjack(self, jack):
#     def _loadclient(self, client):
# def rtuple(obj):
# 
# Path: ejtp/client.py
# class Client(object):
#     def __init__(self, router, interface, encryptor_cache = None, make_jack = True):
#     def send(self, msg):
#     def relay(self, msg):
#     def route(self, msg):
#     def rcv_callback(self, msg, client_obj):
#     def write(self, addr, txt, wrap_sender=True):
#     def owrite(self, hoplist, msg, wrap_sender=True):
#     def owrite_json(self, hoplist, data, wrap_sender=True):
#     def write_json(self, addr, data, wrap_sender=True):
#     def wrap_sender(self, msg):
#     def identity(self):
#     def encryptor_get(self, address):
#     def encryptor_set(self, address, encryptor):
#     def sign(self, obj):
#     def sig_verify(self, obj, signer, sig):
# 
# Path: ejtp/jacks/stream.py
# class Connection(object):
#     '''
#     Represents a persistent connection to a remote host. Should be subclassed.
#     '''
#     def __init__(self, jack=None):
#         self.jack = jack
#         self._buffer = RawData()
#         self._running = False
#         self._outqueue = Queue.Queue()
#         self._thread = threading.Thread(target=self.run)
# 
#     # SUBCLASS INTERFACE ------------------------------------------------------
# 
#     @RawDataDecorator(strict=True)
#     def _send(self, frame):
#         '''
#         Subclass-provided function that sends text to the remote end.
#         '''
#         pass
# 
#     @RawDataDecorator(args=False, ret=True, strict=True)
#     def _recv(self):
#         '''
#         Subclass-provided function that returns text. Allowed to block.
#         '''
#         pass
# 
#     def run(self):
#         '''
#         Network recieve loop.
#         '''
#         pass
# 
#     # PROVIDED BY BASE CLASS --------------------------------------------------
# 
#     def start(self):
#         self._running = True
#         self._thread.start()
# 
#     def close(self):
#         self._running = False
# 
#     def send(self, frame):
#         self._send(self.wrap(frame.content))
# 
#     def recv(self, timeout=0):
#         '''
#         Retrieve from output queue without blocking. Returns None or str.
# 
#         The output queue is only used if self.jack == None.
#         '''
#         try:
#             return self._outqueue.get(timeout=timeout)
#         except Queue.Empty:
#             return None
# 
#     def wrap(self, frame):
#         '''
#         Wrap a frame for transport
#         '''
#         return RawData(format(len(frame), '0x')) + "." + frame        
# 
#     @RawDataDecorator(strict=True)
#     def inject(self, newdata):
#         '''
#         Process new data from the outside world.
#         '''
#         self._buffer += newdata
#         if RawData(".") not in self._buffer:
#             return
#         size, content = self._buffer.split('.',1)
#         size = int(size.export(), 16) # Read size as hex
#         if len(content) < size:
#             return
#         if self.jack:
#             self.jack.recv(content[:size])
#         else:
#             self._outqueue.put(content[:size])
#         self._buffer = content[size:]


# Path: ejtp/tests/test_jacks.py
from ejtp.util.compat import unittest
from persei import String, RawData
from ejtp import router, client
from ejtp.jacks.stream import Connection
import threading


class TestJacks(unittest.TestCase):

    def setUp(self):
        self.routerA = router.Router()
        self.routerB = router.Router()

    def test_udp4(self):
        self.make_test(
            ['udp4', ['127.0.0.1', 18999], 'charlie'],
            ['udp4', ['127.0.0.1', 19999], 'stacy'])

    def test_udp(self):
        self.make_test(
            ['udp', ['::1', 8999], 'charlie'],
            ['udp', ['::1', 9999], 'stacy'])

    def test_tcp4(self):
        self.make_test(
            ['tcp4', ['127.0.0.1', 18999], 'charlie'],
            ['tcp4', ['127.0.0.1', 19999], 'stacy'])

    def test_tcp(self):
        self.make_test(
            ['tcp', ['::1', 8999], 'charlie'],
            ['tcp', ['::1', 9999], 'stacy'])

    def make_test(self, ifaceA, ifaceB, messageAB='A => B', messageBA='B => A', timeout=0.5):
        clientA = client.Client(self.routerA, ifaceA)
        clientB = client.Client(self.routerB, ifaceB)

        self.assertNotEqual(clientA.router, clientB.router)