'''
Created on Mar 15, 2021

@author: Saurabh Kumar Pandey

This scipt will pick its configuration from the config.ini
This worker will split the data to multiple queues to delhi and pune

!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!
Create_User_Xchange -> Create_NonDemo_User_PROD  -> Create_Account_Xchange    -> Create_Account_DELHI
                                                                            -> Create_Account_PUNE
Create_User_Xchange -> Set_User_Pin_PROD  -> Set_User_Pin_Xchange            -> Set_User_Pin_DELHI
                                                                            -> Set_User_Pin_PUNE
Create_User_Xchange -> Update_User_PROD   -> Update_User_Xchange            -> Update_User_DELHI
                                                                            -> Update_User_PUNE
Create_User_Xchange -> Update_User_Profile_PROD  -> Update_User_Profile_Xchange    -> Update_User_Profile_DELHI
                                                                            -> Update_User_Profile_PUNE
Create_User_Xchange -> User_Attempts_Log_PROD  -> User_Attempts_Log_Xchange    -> User_Attempts_Log_DELHI
                                                                            -> User_Attempts_Log_PUNE
Create_User_Xchange -> User_Creation_Log_PROD  -> User_Creation_Log_Xchange    -> User_Creation_Log_DELHI
                                                                            -> User_Creation_Log_PUNE
Create_User_Xchange -> User_Address_PROD  -> User_Address_Xchange            -> User_Address_DELHI
                                                                            -> User_Address_PUNE

'''
#Standard library import
#this will pull the demographic details from Queue and publish it to the MYSQL or mongodb user linking
import pika ,json

from configparser import ConfigParser
from lib.log import logger
from lib.user_type_validation import validation

config_object = ConfigParser()
config_object.read("/opt/rmq-workers/config.ini")
rabbitmq = config_object["rabbitmq"]
application_environment = config_object["environment"]['application']
application_location = config_object["environment"]['location']
prefetch_counter = config_object["prefetch_count"]

#RabbitMQ connection credentials
try:
    credentials = pika.PlainCredentials(rabbitmq['username'], rabbitmq['password'])
    parameters = pika.ConnectionParameters(rabbitmq['host'], rabbitmq['port'], rabbitmq['vhost'], credentials, socket_timeout=int(rabbitmq['socket_timeout']))                                   
    
    #Connection to a broker on the local machine
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()
    
    exchange_name = 'Create_User_Xchange'
    
    #channel.exchange_declare(exchange=exchange_name, exchange_type='fanout', durable=True)
    channel.exchange_declare(exchange=exchange_name, exchange_type='direct', durable=True)
    route_key = queue_name = 'Update_User_Profile_'+ application_environment
    channel.queue_bind(exchange=exchange_name, queue=queue_name, routing_key=route_key)
except Exception as channel_declaration:
    print(channel_declaration) 
    response = {'channel_exception': 'Unable to connect to RMQ', 'msg': channel_declaration }
    logger('accounts_worker_log',response)   

#Receiving messages from the queue is more complex. It works by subscribing a callback function to a queue.
#Whenever we receive a message, this callback function is called by the Pika library.

def user_pin_fanout(q_data):
    try:
        connection_pdf = pika.BlockingConnection(parameters)
        channel_pdf = connection_pdf.channel()
        channel_pdf.exchange_declare(exchange='Update_User_Profile_Xchange', exchange_type='fanout', durable=True)
        channel_pdf.basic_publish(exchange='Update_User_Profile_Xchange', routing_key='', body=q_data)
        connection_pdf.close()
        return  {'status':True}
    except Exception as userException:
        return  {'status':False, 'msg': userException}
           

def callback(ch, method, properties, body):      
    try: 
        set_pin = user_pin_fanout(body)
        if set_pin['status'] == True:
            ch.basic_ack(delivery_tag=method.delivery_tag,multiple=False)
        else:
            response = {'accounts_update_profile_exception': 'splitter queue is mis-configured.'}
            logger('accounts_worker_log',response)
            ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True)
            print(set_pin)
    except Exception as data_expn: 
        response = {'accounts_update_profile_exception': 'Data Exception.', 'data_exception': data_expn}
        logger('accounts_worker_log',response)         
        ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False) 
        
            
channel.basic_qos(prefetch_count= int(prefetch_counter['split-update-profile']))      

try: 
    b = channel.basic_consume(queue=queue_name, on_message_callback = callback)
    channel.start_consuming()   
except Exception as ChannelException:
    response = {'channelException': ChannelException}
    logger('accounts_worker_log',response)      
    print(ChannelException)    
    print('Unable to communicate with RMQ')
    channel.stop_consuming()