'''
Created on 15-Mar-2021
@author: Saurabh Kumar Pandey
Queues used --- 
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

#Local application/Library specific imports
from configparser import ConfigParser
from lib.create_user_mysql_mongo import create_user 
from lib.user_type_validation import validation
from lib.log import logger


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"]
accounts_db = config_object["mongo_accounts_db"]
#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_Account_Xchange'
    
    channel.exchange_declare(exchange=exchange_name, exchange_type='fanout', durable=True)
    route_key = queue_name = 'Create_Account_'+ application_location
    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 callback(ch, method, properties, body):      
    try:    
        data = json.loads(body) 
        content = data['data']     
        user_type = content.get('user_type')
        log_id = data.get('log_id') or None               
        try:                     
            if user_type != None:            
                validation_resp = validation(content, user_type)  
                response =  {'validation': validation_resp}
                logger('accounts_worker_log',response)
                if validation_resp['status'] == True:  
                    createUser = create_user(ch, method, properties, content, user_type, log_id)
                    response =  {'create_user_status': createUser, 'status': 'success', 'log_id': log_id}
                    logger('accounts_worker_log',response)
                    print(createUser)
                else:
                    response = {'createUser_msg': validation_resp, 'status': 'fail', 'log_id': log_id}
                    logger('accounts_worker_log',response)
                    ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False)  
            else:
                ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False) 
                response = {'user_type': 'NA', 'status': 'fail', 'log_id': log_id}
                logger('accounts_worker_log',response) 
        except Exception as flowExpn: 
            ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True)
            response = {'createUser_msg': flowExpn, 'status': 'fail', 'log_id': log_id}
            logger('accounts_worker_log',response)
            print(flowExpn)   
    
    except Exception as data_expn: 
        response = {'req_data':body,'msg': data_expn, 'status': 'fail'}
        logger('accounts_worker_log',response)        
        ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False) 
        
channel.basic_qos(prefetch_count= int(prefetch_counter['accounts-creation'])) 

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)    
    channel.stop_consuming()