# Path: lib/devices.py
# RABBITMQ_ADDRESS = 'localhost'
# 
# Path: lib/utils.py
# def BufferToMatrix(jsonDump, output_type=None):
#     """
#     After retrieving the encoded json from the message queue buffer, we need to translate the 3 element json
#     back into its original form.
#     The 3 elements are:
#     0: use the 0th element to cast correct type
#     1: the base64 encoded data just needs to be base64 decoded
#     2: use the 2nd element to set correct dimensions with reshape()
# 
#     borrowed from: http://stackoverflow.com/questions/13461945/dumping-2d-python-array-with-json
#     :param jsonDump:
#     :return:
#     """
#     # if incoming json has not yet been json decoded, do it
#     if isinstance(jsonDump, str):
#         jsonDump = json.loads(jsonDump)
# 
#     # handle type
#     dtype_string = jsonDump[0]
#     if "DTYPE_" in dtype_string:
#         # if the type
#         dtype = np.dtype(eval(dtype_string))
#     else:
#         dtype = np.dtype(dtype_string)
# 
#     # reconstitute the data, using cast to decoded type from above
#     matrix_array = np.frombuffer(base64.decodestring(jsonDump[1]),dtype)
#     if len(jsonDump) > 2:
#         matrix_array = matrix_array.reshape(jsonDump[2])
# 
#     if output_type is 'list':
#         matrix_list = []
#         vector = []
#         [rows,cols] = matrix_array.shape
#         if dtype_string == "DTYPE_COORD":
#             for row in np.arange(rows):
#                 for column in np.arange(cols):
#                     point = [matrix_array[row][column]["x"],matrix_array[row][column]["y"]]
#                     vector.append(point)
#                 matrix_list.append(vector)
#                 vector = []
#         else:
#             for row in np.arange(rows):
#                 for column in np.arange(cols):
#                     vector.append(matrix_array[row][column])
#                 matrix_list.append(vector)
#                 vector = []
# 
#         return matrix_list
# 
#     return matrix_array
# 
# def ListConfOutputMetrics(conf, prefix=None):
#     """
#     Loop through all of the available output metrics, among all of the modules defined in the conf .yml file.
#     If an option prefix is specified, this will limit response sent to the UI to only include those metrics w/ the prefix
#     """
#     metrics = []
#     print conf['modules']
#     for module in conf['modules']:
#         if 'outputs' in module and 'data' in module['outputs']:
#             if 'message_queues' in module['outputs']['data']:
#                 if type(module['outputs']['data']['message_queues']) == str:
#                     if prefix is None or module['outputs']['data']['message_queues'].startswith(prefix):
#                         metrics.append(module['outputs']['data']['message_queues'])
#                 elif type(module['outputs']['data']['message_queues']) == list:
#                     for metric in module['outputs']['data']['message_queues']:
#                         if prefix is None or metric.startswith(prefix):
#                             metrics.append(metric)
# 
#     return metrics


import json
import logging
from sockjs.tornado.conn import SockJSConnection
from lib.devices import RABBITMQ_ADDRESS
from TornadoSubscriber import TornadoSubscriber
from lib.utils import BufferToMatrix, ListConfOutputMetrics
from lib.constants import *

        # debug
        print "[Tornado Server] Received SUBSCRIBE for Queue [" + device_id + ":" + device_name + ":" + metric + "]"

        if metric not in self.subscribers:
            self.subscribers[metric] = TornadoSubscriber(callback=self.send_probe_factory(metric, data_type),
                                       device_name=device_name,
                                       device_id=device_id,
                                       rabbitmq_address=rabbitmq_address,
                                       metric_name=metric)

        self.subscribers[metric].connect()

    def handle_channel_unsubscription(self, unsubscription_msg):
        # parameters that can be passed in JSON from client
        metric = (unsubscription_msg['metric'] if 'metric' in unsubscription_msg else '')

        # debug
        print "[Tornado Server] Received UNSUBSCRIBE for metric [" + metric + "]"

        if unsubscription_msg['metric'] in self.subscribers:
            self.subscribers[unsubscription_msg['metric']].disconnect()

    def handle_channel_command(self, stream_configuration):
        # parameters that can be passed in JSON from client
        command = (stream_configuration['command'] if "command" in stream_configuration else None)
        device_name = (stream_configuration['deviceName'] if "deviceName" in stream_configuration else None)
        device_id = (stream_configuration['deviceId'] if "deviceId" in stream_configuration else None)
        metric = (stream_configuration['metric'] if "metric" in stream_configuration else None)
        data_type = (stream_configuration['dataType'] if "dataType" in stream_configuration else None)

# Path: lib/devices.py
# RABBITMQ_ADDRESS = 'localhost'
# 
# Path: lib/utils.py
# def BufferToMatrix(jsonDump, output_type=None):
#     """
#     After retrieving the encoded json from the message queue buffer, we need to translate the 3 element json
#     back into its original form.
#     The 3 elements are:
#     0: use the 0th element to cast correct type
#     1: the base64 encoded data just needs to be base64 decoded
#     2: use the 2nd element to set correct dimensions with reshape()
# 
#     borrowed from: http://stackoverflow.com/questions/13461945/dumping-2d-python-array-with-json
#     :param jsonDump:
#     :return:
#     """
#     # if incoming json has not yet been json decoded, do it
#     if isinstance(jsonDump, str):
#         jsonDump = json.loads(jsonDump)
# 
#     # handle type
#     dtype_string = jsonDump[0]
#     if "DTYPE_" in dtype_string:
#         # if the type
#         dtype = np.dtype(eval(dtype_string))
#     else:
#         dtype = np.dtype(dtype_string)
# 
#     # reconstitute the data, using cast to decoded type from above
#     matrix_array = np.frombuffer(base64.decodestring(jsonDump[1]),dtype)
#     if len(jsonDump) > 2:
#         matrix_array = matrix_array.reshape(jsonDump[2])
# 
#     if output_type is 'list':
#         matrix_list = []
#         vector = []
#         [rows,cols] = matrix_array.shape
#         if dtype_string == "DTYPE_COORD":
#             for row in np.arange(rows):
#                 for column in np.arange(cols):
#                     point = [matrix_array[row][column]["x"],matrix_array[row][column]["y"]]
#                     vector.append(point)
#                 matrix_list.append(vector)
#                 vector = []
#         else:
#             for row in np.arange(rows):
#                 for column in np.arange(cols):
#                     vector.append(matrix_array[row][column])
#                 matrix_list.append(vector)
#                 vector = []
# 
#         return matrix_list
# 
#     return matrix_array
# 
# def ListConfOutputMetrics(conf, prefix=None):
#     """
#     Loop through all of the available output metrics, among all of the modules defined in the conf .yml file.
#     If an option prefix is specified, this will limit response sent to the UI to only include those metrics w/ the prefix
#     """
#     metrics = []
#     print conf['modules']
#     for module in conf['modules']:
#         if 'outputs' in module and 'data' in module['outputs']:
#             if 'message_queues' in module['outputs']['data']:
#                 if type(module['outputs']['data']['message_queues']) == str:
#                     if prefix is None or module['outputs']['data']['message_queues'].startswith(prefix):
#                         metrics.append(module['outputs']['data']['message_queues'])
#                 elif type(module['outputs']['data']['message_queues']) == list:
#                     for metric in module['outputs']['data']['message_queues']:
#                         if prefix is None or metric.startswith(prefix):
#                             metrics.append(metric)
# 
#     return metrics


# Path: Viz/Server/Connections.py
import json
import logging
from sockjs.tornado.conn import SockJSConnection
from lib.devices import RABBITMQ_ADDRESS
from TornadoSubscriber import TornadoSubscriber
from lib.utils import BufferToMatrix, ListConfOutputMetrics
from lib.constants import *


        # debug
        print "[Tornado Server] Received SUBSCRIBE for Queue [" + device_id + ":" + device_name + ":" + metric + "]"

        if metric not in self.subscribers:
            self.subscribers[metric] = TornadoSubscriber(callback=self.send_probe_factory(metric, data_type),
                                       device_name=device_name,
                                       device_id=device_id,
                                       rabbitmq_address=rabbitmq_address,
                                       metric_name=metric)

        self.subscribers[metric].connect()

    def handle_channel_unsubscription(self, unsubscription_msg):
        # parameters that can be passed in JSON from client
        metric = (unsubscription_msg['metric'] if 'metric' in unsubscription_msg else '')

        # debug
        print "[Tornado Server] Received UNSUBSCRIBE for metric [" + metric + "]"

        if unsubscription_msg['metric'] in self.subscribers:
            self.subscribers[unsubscription_msg['metric']].disconnect()

    def handle_channel_command(self, stream_configuration):
        # parameters that can be passed in JSON from client
        command = (stream_configuration['command'] if "command" in stream_configuration else None)
        device_name = (stream_configuration['deviceName'] if "deviceName" in stream_configuration else None)
        device_id = (stream_configuration['deviceId'] if "deviceId" in stream_configuration else None)
        metric = (stream_configuration['metric'] if "metric" in stream_configuration else None)
        data_type = (stream_configuration['dataType'] if "dataType" in stream_configuration else None)

        rabbitmq_address = (stream_configuration['rabbitmq_address'] if 'rabbitmq_address' in stream_configuration else RABBITMQ_ADDRESS)