'''
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 = 'User_Attempts_Log_'+ 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='User_Attempts_Log_Xchange', exchange_type='fanout', durable=True)
        channel_pdf.basic_publish(exchange='User_Attempts_Log_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_user_attempts_log_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_user_attempts_log_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-user-attempts-log']))      

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()