package in.gov.digilocker.uidai.logs.sender;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import in.gov.digilocker.uidai.logs.config.RabbitMQConfiguration;

@Service
public class MessageSendTaskExecutor {
	private static final Logger logger= LoggerFactory.getLogger(MessageSendTaskExecutor.class);
	
	@Autowired RabbitMQConfiguration rabbitMqConfig;
	@Autowired ConnectionFactory connectionFactory;
	@Autowired ThreadPoolTaskExecutor taskExecutor;
	
	public void executeTask(JSONObject message, String messageType, String collectionName, String dbName) {		
		taskExecutor.execute(new MessageSenderTask(message, messageType, collectionName, dbName));	
	}
	
	public void executeTask(JSONObject message, String messageType, String aadhaarNumber, String collectionName, String dbName) {		
		taskExecutor.execute(new MessageSenderTask(message, messageType, aadhaarNumber, collectionName, dbName));	
	}
	
	
	
	private class MessageSenderTask implements Runnable {		
		private JSONObject message; 
		private String messageType;
		private String collectionName; 
		private String dbName;
		private String aadhaarNumber;
		
		public MessageSenderTask(JSONObject message, String messageType, String collectionName, String dbName) {
			this.message= message; 
			this.messageType= messageType;
			this.collectionName= collectionName;
			this.dbName= dbName;		
		}
		
		
		public MessageSenderTask(JSONObject message, String messageType, String aadhaarNumber, String collectionName, String dbName) {			
			this.message= message; 
			this.messageType= messageType;
			this.collectionName= collectionName;
			this.dbName= dbName;
			this.aadhaarNumber= aadhaarNumber;
		}
		
		@Override
		public void run() {						
			Connection conn= null;
			Channel channel= null;
			String finalMessage= "";			
			JSONObject obj= new JSONObject();			
			try {
				obj.put("operation", messageType);
				obj.put("db", dbName);
				obj.put("collection", collectionName);
				obj.put("data", message);
				conn= connectionFactory.newConnection();
				channel= conn.createChannel();			
				if (messageType.equalsIgnoreCase(rabbitMqConfig.getRabbitMqUpdateType())) {
					JSONObject uObj= new JSONObject();
					uObj.put("aadhaar_number", aadhaarNumber);
					obj.put("key", uObj);
					obj.put("multi", "N");
					finalMessage= obj.toString();					
					channel.basicPublish(rabbitMqConfig.getRabbitMqExchaneName(), 
							rabbitMqConfig.getRabbitMqUpdateRoutingKey(), 
							new AMQP.BasicProperties.Builder()
							.contentType("application/json")
				            .deliveryMode(2)
				            .priority(1)				            
				            .build(), finalMessage.getBytes());
				} else if (messageType.equalsIgnoreCase(rabbitMqConfig.getRabbitMqInsertType())) {
					finalMessage= obj.toString();					
					channel.basicPublish(rabbitMqConfig.getRabbitMqExchaneName(), 
							rabbitMqConfig.getRabbitMqInsertRoutingKey(), 
							new AMQP.BasicProperties.Builder()
							.contentType("application/json")
				            .deliveryMode(2)
				            .priority(1)	               
				            .build(), finalMessage.getBytes());					
				}				
				if(null != channel) {
					channel.close();
				}
				if(null != conn) {
					conn.close();
				}				
			} catch (IOException | TimeoutException | JSONException e) {
				logger.info("Exception in task execution: " +e.getMessage());
				//e.printStackTrace();
			}
		}		
	}	
}
