'''
Created on 27-Jul-2020

@author: Saurabh Kumar Pandey
This script is the worker which aims at performing the set pin of user in mysql and mongodb
'''
#Standard library import
#this will pull the demographic details from Queue and publish it to the MYSQL or mongodb user linking
import pika,json,datetime,uuid
from datetime import date, timedelta
from lib.create_user_mysql_mongo import mongoUpdateOperator
from lib.log import logger
from configparser import ConfigParser
import hashlib 

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 = 'Update_User_Xchange'    
    channel.exchange_declare(exchange=exchange_name, exchange_type='fanout', durable=True)
    route_key = queue_name = 'Update_User_'+ 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)    
        
def updateUser(ch, method, properties, content, log_id):
    global userMongoData, refkey
    ''' This content will have userid and pin that needs to be updated to the userser in Mongo, Mysql and Redis'''
    userMongoData = {}
    try:    
        if content.get('digilockerid') != None:        
            try:
                now = datetime.datetime.now()
                if content.get('mobile_no') != None:    
                    userMongoData['mobile_no'] = content['mobile_no']
                    
                if content.get('device_id') != None:    
                    userMongoData['device_id'] = content['device_id']
                    
                if content.get('email_id') != None:    
                    userMongoData['email_id'] = content.get('email_id')
                    
                if content.get('email_id_verified') != None:    
                    userMongoData['email_id_verified'] = content.get('email_id_verified')  
                                  
                if content.get('refkey') != None:    
                    userMongoData['refkey'] = content.get('refkey')  
                                  
                if content.get('uid') != None:    
                    userMongoData['uid'] = content.get('uid')    
                                       
                if content.get('uid_token') != None:    
                    userMongoData['uid_token'] = content.get('uid_token') 
                
                if content.get('uid_token') != None:    
                    userMongoData['uid_token_hash'] = hashlib.md5(content.get('uid_token').encode('utf-8')).hexdigest()    
                          
                      
                if content.get('created_by') != None:
                    userMongoData['created_by'] = content.get('created_by')
                    
                if content.get('user_id') != None:                
                    userMongoData['user_id'] = content.get('user_id')  
					
                if content.get('user_alias') != None:                
                    userMongoData['user_alias'] = content.get('user_alias')					 
                     
                if content.get('user_type') != None:       
                    userMongoData['user_type'] = content.get('user_type')
                    
                if content.get('user_enc_key') != None:      
                    userMongoData['user_enc_key'] = content.get('user_enc_key') 
                    
                if content.get('device_id') != None:      
                    userMongoData['device_id'] = content.get('device_id')    
                     
                if content.get('is_deleted') != None:     
                    userMongoData['is_deleted'] = content.get('is_deleted')   
                    
                if content.get('created_on') != None:       
                    created_on = datetime.datetime.strptime(content['created_on'], '%Y-%m-%d')                    
                    userMongoData['created_on'] = created_on  
                    
                if content.get('security_question_id') != None:          
                    userMongoData['security_question_id'] = content.get('security_question_id')
                    
                if content.get('email_id_verified') != None:     
                    userMongoData['email_id_verified'] = content.get('email_id_verified')   
                         
                if content.get('option1') != None:     
                    userMongoData['option1'] = content.get('option1')
                    
                if content.get('option2') != None:     
                    userMongoData['option2'] = content.get('option2')
                    
                if content.get('option3') != None:     
                    userMongoData['option3'] = content.get('option3')   
                     
                if content.get('uploaded_doc_path') != None: 
                    userMongoData['uploaded_doc_path'] = content.get('uploaded_doc_path')
                    
                if content.get('health_doc_path') != None: 
                    userMongoData['health_doc_path'] = content.get('health_doc_path')
                    
                if content.get('issued_doc_path') != None: 
                    userMongoData['issued_doc_path'] = content.get('issued_doc_path')
                    
                if content.get('photo') != None:       
                    userMongoData['photo'] = content.get('photo')               
      
                userMongoData['modified_on'] = now
      
                    
                try:
                    dataUpdUser = { "operation": "U",
                        "db": accounts_db["accounts_db"],
                        "collection": 'users',
                        "data": userMongoData,
                        "key": {'digilockerid':content['digilockerid']},
                        "multi":'N'}
    
                    mongorespProfile = mongoUpdateOperator(dataUpdUser)
                    
                    if mongorespProfile['status'] == True and mongorespProfile['msg'][0] == 1: 
                        ch.basic_ack(delivery_tag=method.delivery_tag,multiple=False)
                        return {'status': True, 'msg' : 'UserUpated'}               
                      
                    elif mongorespProfile['status'] == False:
                        if mongorespProfile['code']  in {2, 3, 0 }: 
                            ch.basic_ack(delivery_tag=method.delivery_tag,multiple=False)
                    else:
                        ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True) 
                        return {'status': False, 'msg' : ('profileWrite', 'error 217')}
                except Exception as rmqPublishError:
                    ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True) 
                    return {'status':False, 'msg':rmqPublishError}
                         
            except Exception as dataError:
                ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False) 
                return {'status':False, 'msg':dataError}   
        else:            
            ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False)
            return {'status': False, 'msg' : 'digilockerid not defined'}
                 
    except Exception as dataError:
        ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True) 
        return {'status':False, 'msg':dataError}       

def callback(ch, method, properties, body):
    try:    
        data = json.loads(body)   
        content = data.get('data')
        log_id = data.get('id') or None
        resp = updateUser(ch, method, properties, content, log_id)
        response =  {'user_update':resp, 'log_id': log_id}
        logger('accounts_worker_log',response)
        print(resp)            
    except Exception as functinal_expn:
        response =  {'prof_update_error': 'exception raised', 'log_id': log_id, 'msg': functinal_expn}
        logger('accounts_worker_log',response)
        print(functinal_expn)
        ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True)        
        
        
channel.basic_qos(prefetch_count=int(prefetch_counter['accounts-update-users']))        
try: 
    b = channel.basic_consume(queue=queue_name, on_message_callback = callback)
    channel.start_consuming()   
except Exception as ChannelException:
    response = {'channel_exception': 'Unable to connect to RMQ', 'msg': ChannelException}
    logger('accounts_worker_log',response)
    print(ChannelException)    
    channel.stop_consuming()
