# Path: lib/SubscriberInterface.py
# class Subscriber(object):
#   __metaclass__ = ABCMeta
#   
#   def __init__(self,  device_name, device_id, host):
#     """
#     
#     :return:
#     """
#     self.device_name = device_name
#     self.device_id = device_id
#     self.host = host
# 
#   @abstractmethod
#   def consume_messages(self, callback):
#     #TODO: write doc
#     """
#     
#     :return:
#     """
#   @abstractmethod
#   def connect(self):
#     #TODO: write doc
#     """
#     
#     :return:
#     """
#     
#   @abstractmethod
#   def disconnect(self):
#     #TODO: write doc
#     """
#     
#     :return:
#     """
# 
# Path: lib/constants.py
# class colors:
#     ENDC = '\033[0m'
#     UNDERLINE = '\033[4m'
#     BLINK = '\033[5m'
# 
#     HEADER = '\033[95m'
#     OKBLUE = '\033[94m'
#     OKGREEN = '\033[92m'
#     FAIL = '\033[91m'
# 
#     BG_RASPBERRY = '\033[46m'
# 
#     DARK_RED = '\033[0;31m'
#     RED = '\033[91m'
#     ORANGE = '\033[1m'
#     YELLOW = '\033[93m'
#     GREEN = '\033[92m'
#     DARK_GREEN = '\033[0;32m'
#     CYAN = '\033[96m'
#     MAGENTA = '\033[0;35m'
#     RASPBERRY = '\033[0;36m'
#     DARK_PURPLE = '\033[0;34m'
# 
#     GOLD = '\033[0;33m'
#     SILVER = '\033[0;37m'
#     GRAY = '\033[90m'
# 
#     BOLD_RED = '\033[1;31m'
#     BOLD_ORANGE = '\033[1m'
#     BOLD_YELLOW = '\033[1;33m'
#     BOLD_GREEN = '\033[1;32m'
#     BOLD_CYAN = '\033[1;36m'
#     BOLD_BLUE  = '\033[1;34m'
#     BOLD_PURPLE = '\033[1;35m'
#     BOLD_GRAY  = '\033[1;30m'
# 
#     CYCLE = [YELLOW, GREEN, ORANGE,  RASPBERRY, DARK_RED, CYAN, RED, DARK_GREEN, MAGENTA, DARK_PURPLE]


import pika
from lib.SubscriberInterface import Subscriber
from lib.constants import colors


  def connect(self):
    credentials = pika.PlainCredentials('cloudbrain', 'cloudbrain')
    self.connection = pika.BlockingConnection(pika.ConnectionParameters(
      host=self.host, credentials=credentials))
    self.channel = self.connection.channel()

    for metric_id,metric_info in self.metrics.iteritems():
        # each metric has an internal id, and a name
        #
        # the internal id is used as a consumer_tag, or think of it as a hardcoded local variable
        # for example, if i have 2 inputs [class_label, data], the 2 inputs are not interchangeable,
        # and we must know which is which, so we use their ids to identify them
        #
        # the name is used to find the correct exchange in rabbitmq
        key = "%s:%s:%s" %(self.device_id,self.device_name, metric_info['name'])
        # declare the exchange serving this metric
        self.channel.exchange_declare(exchange=key, exchange_type='direct')

        # declare queue and bind
        # exclusive=True is important to make a queue that will be destroyed when client hangs up
        # otherwise the queue would persist to the next session, with some old data still stuck in it
        #
        # Another thing, someone might look at this queue declaration and wonder: why didn't we pass in
        # the queue name as a parameter like everywhere else?  The reason for this is that, by not passing in
        # a name, we allow pika to use a randomly generated name for the queue
        self.queues[metric_id] = self.channel.queue_declare(exclusive=True).method.queue
        self.channel.queue_bind(exchange=key, queue=self.queues[metric_id], routing_key=key)


# Path: lib/SubscriberInterface.py
# class Subscriber(object):
#   __metaclass__ = ABCMeta
#   
#   def __init__(self,  device_name, device_id, host):
#     """
#     
#     :return:
#     """
#     self.device_name = device_name
#     self.device_id = device_id
#     self.host = host
# 
#   @abstractmethod
#   def consume_messages(self, callback):
#     #TODO: write doc
#     """
#     
#     :return:
#     """
#   @abstractmethod
#   def connect(self):
#     #TODO: write doc
#     """
#     
#     :return:
#     """
#     
#   @abstractmethod
#   def disconnect(self):
#     #TODO: write doc
#     """
#     
#     :return:
#     """
# 
# Path: lib/constants.py
# class colors:
#     ENDC = '\033[0m'
#     UNDERLINE = '\033[4m'
#     BLINK = '\033[5m'
# 
#     HEADER = '\033[95m'
#     OKBLUE = '\033[94m'
#     OKGREEN = '\033[92m'
#     FAIL = '\033[91m'
# 
#     BG_RASPBERRY = '\033[46m'
# 
#     DARK_RED = '\033[0;31m'
#     RED = '\033[91m'
#     ORANGE = '\033[1m'
#     YELLOW = '\033[93m'
#     GREEN = '\033[92m'
#     DARK_GREEN = '\033[0;32m'
#     CYAN = '\033[96m'
#     MAGENTA = '\033[0;35m'
#     RASPBERRY = '\033[0;36m'
#     DARK_PURPLE = '\033[0;34m'
# 
#     GOLD = '\033[0;33m'
#     SILVER = '\033[0;37m'
#     GRAY = '\033[90m'
# 
#     BOLD_RED = '\033[1;31m'
#     BOLD_ORANGE = '\033[1m'
#     BOLD_YELLOW = '\033[1;33m'
#     BOLD_GREEN = '\033[1;32m'
#     BOLD_CYAN = '\033[1;36m'
#     BOLD_BLUE  = '\033[1;34m'
#     BOLD_PURPLE = '\033[1;35m'
#     BOLD_GRAY  = '\033[1;30m'
# 
#     CYCLE = [YELLOW, GREEN, ORANGE,  RASPBERRY, DARK_RED, CYAN, RED, DARK_GREEN, MAGENTA, DARK_PURPLE]


# Path: lib/PikaSubscriber.py
import pika
from lib.SubscriberInterface import Subscriber
from lib.constants import colors



  def connect(self):
    credentials = pika.PlainCredentials('cloudbrain', 'cloudbrain')
    self.connection = pika.BlockingConnection(pika.ConnectionParameters(
      host=self.host, credentials=credentials))
    self.channel = self.connection.channel()

    for metric_id,metric_info in self.metrics.iteritems():
        # each metric has an internal id, and a name
        #
        # the internal id is used as a consumer_tag, or think of it as a hardcoded local variable
        # for example, if i have 2 inputs [class_label, data], the 2 inputs are not interchangeable,
        # and we must know which is which, so we use their ids to identify them
        #
        # the name is used to find the correct exchange in rabbitmq
        key = "%s:%s:%s" %(self.device_id,self.device_name, metric_info['name'])
        # declare the exchange serving this metric
        self.channel.exchange_declare(exchange=key, exchange_type='direct')

        # declare queue and bind
        # exclusive=True is important to make a queue that will be destroyed when client hangs up
        # otherwise the queue would persist to the next session, with some old data still stuck in it
        #
        # Another thing, someone might look at this queue declaration and wonder: why didn't we pass in
        # the queue name as a parameter like everywhere else?  The reason for this is that, by not passing in
        # a name, we allow pika to use a randomly generated name for the queue
        self.queues[metric_id] = self.channel.queue_declare(exclusive=True).method.queue
        self.channel.queue_bind(exchange=key, queue=self.queues[metric_id], routing_key=key)


        print colors.GOLD + "[Subscriber Started] Queue --> [" + key + "] for input [" + metric_id + "]" + colors.ENDC