import sys
import os
import socket
import time

from pika import BasicProperties


class AMQPQueue:

    args = None

    # User arguments
    count = 0
    delay = 0

    # AMQP settings
    exchange_name = None
    queue_name = None
    routing_key = None

    def __init__(self, args):
        self.args = args
        self._init_config()

    def _init_config(self):
        self.exchange_name = self.args.exchange_name
        self.queue_name = self.args.queue_name
        self.routing_key = self.args.routing_key

        if 'count' in self.args:
            self.count = self.args.count

        if 'delay' in self.args:
            self.delay = self.args.delay

    def setup(self, connection):
        channel = connection.channel()

        channel.exchange_declare(exchange=self.exchange_name, type='topic')
        channel.queue_declare(queue=self.queue_name, durable=True)
        channel.queue_bind(
            exchange=self.exchange_name,
            queue=self.queue_name,
            routing_key=self.routing_key
        )
        connection.close()

        print "Queue setup completed"

    def consumer(self, channel):
        channel.queue_declare(self.queue_name, durable=True)
        channel.basic_consume(
            self._message_consumed,
            self.queue_name,
            no_ack=True
        )
        print ' [*] Waiting for messages. To exit press CTRL+C'
        print '==============================================='
        channel.start_consuming()

    def _message_consumed(self, channel, method, properties, body):
        print " [x] message payload: %r" % body
        if self.delay > 0:
            print "  ZzZzZ sleeping %d secs" % self.delay
            time.sleep(self.delay)

    def publish_message(self, channel, current):
        self._print_progress()
        try:
            channel.basic_publish(
                exchange=self.exchange_name,
                routing_key=self.routing_key,
                body=self.generate_message(current),
                properties=BasicProperties(
                    content_type="text/plain",
                    delivery_mode=1
                )
            )
        except:
            print "error with publishing to channel: ", sys.exc_info()[0]
            raise

    def generate_message(self, current):
        return "HA mirroring test from %s (pid: %d), message %d of %d" % (
                socket.gethostname(),
                os.getpid(),
                current + 1,
                self.count
            )

    @staticmethod
    def print_final_progress(current, total):
        print "(", current, "/", total, ")"

    @staticmethod
    def _print_progress():
        sys.stdout.write('.')
        sys.stdout.flush()

    @staticmethod
    def finish(total):
        print "\npublished", int(total), "messages"
