# Path: coolamqp/clustering/events.py
# class Event(object):
# class NothingMuch(Event):
# class ConnectionLost(Event):
# class MessageReceived(ReceivedMessage, Event):
#     def __init__(self, msg):  # type: (ReceivedMessage) -> None
# 
# Path: coolamqp/objects.py
# class Queue(object):
#     """
#     This object represents a Queue that applications consume from or publish to.
#     """
#     __slots__ = ('name', 'durable', 'exchange', 'auto_delete', 'exclusive',
#                  'anonymous', 'consumer_tag')
# 
#     def __init__(self, name=b'',  # type: tp.Union[str, bytes]
#                  durable=False,  # type: bool
#                  exchange=None,  # type: tp.Optional[Exchange]
#                  exclusive=False,  # type: bool
#                  auto_delete=False  # type: bool
#                  ):
#         """
#         Create a queue definition.
# 
#         :param name: name of the queue.
#             Take special care if this is empty. If empty, this will be filled-in by the broker
#             upon declaration. If a disconnect happens, and connection to other node is
#             reestablished, this name will CHANGE AGAIN, and be reflected in this object.
#             This change will be done before CoolAMQP signals reconnection.
#         :param durable: Is the queue durable?
#         :param exchange: Exchange for this queue to bind to. None for no binding.
#         :param exclusive: Is this queue exclusive?
#         :param auto_delete: Is this queue auto_delete ?
#         """
#         self.name = tobytes(name)  #: public, must be bytes
#         # if name is '', this will be filled in with broker-generated name upon declaration
#         self.durable = durable
#         self.exchange = exchange
#         self.auto_delete = auto_delete
#         self.exclusive = exclusive
# 
#         self.anonymous = len(
#             self.name) == 0  # if this queue is anonymous, it must be regenerated upon reconnect
# 
#         self.consumer_tag = self.name if not self.anonymous else uuid.uuid4().hex.encode(
#             'utf8')  # bytes, consumer tag to use in AMQP comms
# 
#         assert isinstance(self.name, six.binary_type)
#         assert isinstance(self.consumer_tag, six.binary_type)
# 
#     def __eq__(self, other):
#         return (self.name == other.name) and (type(self) == type(other))
# 
#     def __hash__(self):
#         return hash(self.name)
# 
# class Message(object):
#     """
#     An AMQP message. Has a binary body, and some properties.
# 
#     Properties is a highly regularized class - see
#     coolamqp.framing.definitions.BasicContentPropertyList
#     for a list of possible properties.
# 
#     :param body: stream of octets
#     :type body: anything with a buffer interface
#     :param properties: AMQP properties to be sent along.
#                        default is 'no properties at all'
#                        You can pass a dict - it will be passed to
#                        MessageProperties,
#                        but it's slow - don't do that.
#     :type properties: MessageProperties instance, None or a dict (SLOW!)
# 
#     """
#     __slots__ = ('body', 'properties')
# 
#     Properties = MessageProperties  # an alias for easier use
# 
#     def __init__(self, body,         # type: bytes
#                  properties=None     # type: tp.Optional[MessageProperties]
#                  ):
#         """
#         Create a Message object.
# 
#         Please take care with passing empty bodies, as py-amqp has some
#         failure on it.
#         """
#         if isinstance(body, six.text_type):
#             raise TypeError(u'body cannot be a text type!')
# 
#         self.body = body
# 
#         if isinstance(properties, dict):
#             self.properties = MessageProperties(**properties)
#         elif properties is None:
#             self.properties = EMPTY_PROPERTIES
#         else:
#             self.properties = properties
# 
# Path: stress_tests/settings.py
# NODE = NodeDefinition(os.environ.get('AMQP_HOST', '127.0.0.1'), 'guest', 'guest', heartbeat=20)
# def connect(on_fail=lambda: None, log_frames=None):
#     def _on_fail():
#     def __init__(self, path):
#     def close(self):
#     def on_frame(self, timestamp, frame, direction):
# class LogFramesToFile:


import logging
from satella.coding.concurrent import TerminableThread
from coolamqp.clustering.events import ReceivedMessage
from coolamqp.objects import Queue, Message
from .settings import queue_names, connect, LogFramesToFile




class Server(TerminableThread):
    def __init__(self, amqp):
        self.amqp = amqp
        super().__init__()
        self.consumers = []
        for queue_name in queue_names:
            cons, fut = self.amqp.consume(Queue(queue_name + '-repl'))
            self.consumers.append(cons)

    def loop(self):
        evt = self.amqp.drain(timeout=1.0)

# Path: coolamqp/clustering/events.py
# class Event(object):
# class NothingMuch(Event):
# class ConnectionLost(Event):
# class MessageReceived(ReceivedMessage, Event):
#     def __init__(self, msg):  # type: (ReceivedMessage) -> None
# 
# Path: coolamqp/objects.py
# class Queue(object):
#     """
#     This object represents a Queue that applications consume from or publish to.
#     """
#     __slots__ = ('name', 'durable', 'exchange', 'auto_delete', 'exclusive',
#                  'anonymous', 'consumer_tag')
# 
#     def __init__(self, name=b'',  # type: tp.Union[str, bytes]
#                  durable=False,  # type: bool
#                  exchange=None,  # type: tp.Optional[Exchange]
#                  exclusive=False,  # type: bool
#                  auto_delete=False  # type: bool
#                  ):
#         """
#         Create a queue definition.
# 
#         :param name: name of the queue.
#             Take special care if this is empty. If empty, this will be filled-in by the broker
#             upon declaration. If a disconnect happens, and connection to other node is
#             reestablished, this name will CHANGE AGAIN, and be reflected in this object.
#             This change will be done before CoolAMQP signals reconnection.
#         :param durable: Is the queue durable?
#         :param exchange: Exchange for this queue to bind to. None for no binding.
#         :param exclusive: Is this queue exclusive?
#         :param auto_delete: Is this queue auto_delete ?
#         """
#         self.name = tobytes(name)  #: public, must be bytes
#         # if name is '', this will be filled in with broker-generated name upon declaration
#         self.durable = durable
#         self.exchange = exchange
#         self.auto_delete = auto_delete
#         self.exclusive = exclusive
# 
#         self.anonymous = len(
#             self.name) == 0  # if this queue is anonymous, it must be regenerated upon reconnect
# 
#         self.consumer_tag = self.name if not self.anonymous else uuid.uuid4().hex.encode(
#             'utf8')  # bytes, consumer tag to use in AMQP comms
# 
#         assert isinstance(self.name, six.binary_type)
#         assert isinstance(self.consumer_tag, six.binary_type)
# 
#     def __eq__(self, other):
#         return (self.name == other.name) and (type(self) == type(other))
# 
#     def __hash__(self):
#         return hash(self.name)
# 
# class Message(object):
#     """
#     An AMQP message. Has a binary body, and some properties.
# 
#     Properties is a highly regularized class - see
#     coolamqp.framing.definitions.BasicContentPropertyList
#     for a list of possible properties.
# 
#     :param body: stream of octets
#     :type body: anything with a buffer interface
#     :param properties: AMQP properties to be sent along.
#                        default is 'no properties at all'
#                        You can pass a dict - it will be passed to
#                        MessageProperties,
#                        but it's slow - don't do that.
#     :type properties: MessageProperties instance, None or a dict (SLOW!)
# 
#     """
#     __slots__ = ('body', 'properties')
# 
#     Properties = MessageProperties  # an alias for easier use
# 
#     def __init__(self, body,         # type: bytes
#                  properties=None     # type: tp.Optional[MessageProperties]
#                  ):
#         """
#         Create a Message object.
# 
#         Please take care with passing empty bodies, as py-amqp has some
#         failure on it.
#         """
#         if isinstance(body, six.text_type):
#             raise TypeError(u'body cannot be a text type!')
# 
#         self.body = body
# 
#         if isinstance(properties, dict):
#             self.properties = MessageProperties(**properties)
#         elif properties is None:
#             self.properties = EMPTY_PROPERTIES
#         else:
#             self.properties = properties
# 
# Path: stress_tests/settings.py
# NODE = NodeDefinition(os.environ.get('AMQP_HOST', '127.0.0.1'), 'guest', 'guest', heartbeat=20)
# def connect(on_fail=lambda: None, log_frames=None):
#     def _on_fail():
#     def __init__(self, path):
#     def close(self):
#     def on_frame(self, timestamp, frame, direction):
# class LogFramesToFile:


# Path: stress_tests/server.py
import logging
from satella.coding.concurrent import TerminableThread
from coolamqp.clustering.events import ReceivedMessage
from coolamqp.objects import Queue, Message
from .settings import queue_names, connect, LogFramesToFile





class Server(TerminableThread):
    def __init__(self, amqp):
        self.amqp = amqp
        super().__init__()
        self.consumers = []
        for queue_name in queue_names:
            cons, fut = self.amqp.consume(Queue(queue_name + '-repl'))
            self.consumers.append(cons)

    def loop(self):
        evt = self.amqp.drain(timeout=1.0)

        if isinstance(evt, ReceivedMessage):