'''
Created on 15-May-2020

@author: Saurabh Kumar Pandey
This script is the worker which aims at performing the Logs writing
'''
#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
from datetime import date, timedelta
from lib.create_user_mysql_mongo import mongoUpsertOperator, mongoUpdateLog
from lib.log import logger
from configparser import ConfigParser

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 = 'User_Creation_Log_Xchange'    
    channel.exchange_declare(exchange=exchange_name, exchange_type='fanout', durable=True)
    route_key = queue_name = 'User_Creation_Log_'+ 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 callback(ch, method, properties, body):
    global resp    
    ch.basic_ack(delivery_tag=method.delivery_tag,multiple=False)
    try:    
        data = json.loads(body) 
        log_id = data.get('log_id') or None
        request_type = data.get('request_type') or None
        log_data = data.get('data')
        source = data.get('source')
        
        if request_type !=None:
            logged = logMongo(log_id, request_type, log_data, source)
            if logged['status'] == True and logged['code'] == 1:
                ch.basic_ack(delivery_tag=method.delivery_tag,multiple=False)
            elif logged['status'] == False and logged['code'] in (2, 3):
                ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False)
            else:
                ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False)  
        else:
            logged = logUpdateMongo(log_id, log_data, request_type, source)
            if logged['status'] == True and logged['code'] == 1:
                ch.basic_ack(delivery_tag=method.delivery_tag,multiple=False)
            elif logged['status'] == False and logged['code'] in (2, 3):
                ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False)
            else:
                ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False)               
    except Exception as functinal_expn:
        print(functinal_expn)
        ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True)
        
def logMongo(log_id, request_type, log_data, source):    
    log = {'log_id':log_id, 'log_type': request_type, 'log_data': log_data, 'workerStartTime': datetime.datetime.now()}    
    log_data = {"db": cfg.log_transactions["db"], 
                "collection":cfg.log_transactions["collection"] + '_' +source,
                "operation": "U",
                "data": log,
                "key": {'log_id':log_id},
                "multi":'N'
                
                }
    return mongoUpsertOperator(log_data)


def logUpdateMongo(log_id, log_data, request_type, source):    
    
    log = log_data   
    if request_type != None :
        log = {'log_type': request_type, 'log_data': log_data, 'workerStartTime': datetime.datetime.now()}
         
    log_conf = {"db": cfg.log_transactions["db"], 
                "collection":cfg.log_transactions["collection"] + '-' + source,
                "operation": "U",
                "data": log,
                "key": {'log_id':log_id},
                "multi":'N'
                
                }
    
    return mongoUpdateLog(log_conf)
                        
channel.basic_qos(prefetch_count=cfg.prefetch_count['user_logs'])          
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()