'''
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 mongoUpsertOperator
from configparser import ConfigParser
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 = 'Update_User_Profile_Xchange'
    channel.exchange_declare(exchange=exchange_name, exchange_type='fanout', durable=True)
    route_key = queue_name = 'Update_User_Profile_'+ 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 updateUserProfile(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'''
    userProfileMongoData = {}
    try:    
        if content.get('digilockerid') != None:        
            try:
                now = datetime.datetime.now()
                if content.get('date_of_birth') != None:
                    dob = datetime.datetime.strptime(content['date_of_birth'], '%Y-%m-%d')   
                    userProfileMongoData['date_of_birth'] = dob
                if content.get('name') != None:    
                    userProfileMongoData['name'] = content['name']
                if content.get('gender') != None:    
                    userProfileMongoData['gender'] = content['gender']
                if content.get('state') != None:    
                    userProfileMongoData['state'] = content.get('state')
                if content.get('district') != None:    
                    userProfileMongoData['district'] = content.get('district')
                if content.get('city') != None:
                    userProfileMongoData['city'] = content.get('city')

                if content.get('photo') != None:
                    userProfileMongoData['photo'] = content.get('photo')                
                if content.get('user_from') != None:
                    userProfileMongoData['user_from'] = content.get('user_from')                    
                if content.get('account_type') != None:
                    userProfileMongoData['account_type'] = content.get('account_type')                      
                if content.get('converted_on') != None:
                    converted_on = datetime.datetime.strptime(content['converted_on'], '%Y-%m-%d')   
                    userProfileMongoData['converted_on'] = converted_on                    
                if content.get('converted_by') != None:
                    userProfileMongoData['converted_by'] = content.get('converted_by')                      
                if content.get('account_type') != None:
                    userProfileMongoData['account_type'] = content.get('account_type')      
                                    
                if content.get('uploaded_doc_path') != None: 
                    userProfileMongoData['uploaded_doc_path'] = content.get('uploaded_doc_path')                      
                if content.get('health_doc_path') != None:
                    userProfileMongoData['health_doc_path'] = content.get('health_doc_path')                      
                if content.get('issued_doc_path') != None:
                    userProfileMongoData['issued_doc_path'] = content.get('issued_doc_path')
                                          
                if content.get('created_on') != None:
                    created_on = datetime.datetime.strptime(content['created_on'], '%Y-%m-%d')   
                    userProfileMongoData['created_on'] = created_on  
                                         
                if content.get('option1') != None:
                    userProfileMongoData['option1'] = content.get('option1')                      
                if content.get('option2') != None:
                    userProfileMongoData['option2'] = content.get('option2')                      
                if content.get('option3') != None:
                    userProfileMongoData['option3'] = content.get('option3')    
                                       
                if content.get('email_subscription') != None:    
                    userProfileMongoData['email_subscription'] = content.get('email_subscription')
                                                        
                userProfileMongoData['modified_on'] = now 
                    
                try:
                    dataUpdUser = { "operation": "U",
                        "db": accounts_db["accounts_db"],
                        "collection": 'users_profile',
                        "data": userProfileMongoData,
                        "key": {'digilockerid':content['digilockerid']},
                        "multi":'N'}
    
                    mongorespProfile = mongoUpsertOperator(dataUpdUser)
                    
                    if mongorespProfile['status'] == True and mongorespProfile['code'] == 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 = updateUserProfile(ch, method, properties, content, log_id)
        response = {'prof_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['update-user-profile']))        
try: 
    b = channel.basic_consume(queue=queue_name, on_message_callback = callback)
    channel.start_consuming()   
except Exception as ChannelException:
    print(ChannelException)
    response = {'channel_exception': 'Unable to connect to RMQ', 'msg': ChannelException}
    logger('accounts_worker_log',response)   
    channel.stop_consuming()
