package com.ejie.aa20b.message;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.annotation.Resource;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ejie.aa20b.util.Aa20bParametros;


import com.ejie.aa20b.util.Aa20bConstantes;
import com.ejie.x38.json.JSONArray;
import com.ejie.x38.json.JSONObject;




public class Aa20bProcessMessage {
	
	private Message message;
	
	private javax.jms.Connection jmsConnection;
    private javax.jms.Destination errorQueue;
    
    
	
	@Resource
    private MessageDrivenContext context;
	
		
	
	/**
	 * Constructor por defecto
	 * 
	 * @param message
	 *            : Objeto de tipo Message con el mensaje de evento en
	 *            Tramitagune capturado por la clase MDB
	 */
	public Aa20bProcessMessage(Message message,javax.jms.Connection jmsConnection, javax.jms.Destination errorQueue) {
		this.message = message;
		this.jmsConnection = jmsConnection;
		this.errorQueue = errorQueue;
	}
	
	private static final Logger logger = LoggerFactory
	.getLogger(Aa20bProcessMessage.class);
	
	/**
	 * Método que contiene la lógica de procesamiento del mensaje de evento
	 */
	public void onMessage() {
		
		Aa20bProcessMessage.logger.info("(onMessage) Recuperando objeto del mensaje del evento");		
		
    	try{
    		int operacion = message.getIntProperty("operacion");
    		Aa20bProcessMessage.logger.info("Operacion JMS " + operacion);
    		
    		if (message instanceof TextMessage) {
    			Aa20bProcessMessage.logger.info("Es mensaje texto");
    		}
    		
    		switch(operacion){
    		
    			case Aa20bConstantes.OPER_MANT_EDIF:{
    				
    				com.ejie.aa20b.model.Edificios edificio = (com.ejie.aa20b.model.Edificios) ((ObjectMessage)message).getObject();
    				String urlConfig = Aa20bParametros.get("movilgmao.path");
    				
    				
    				boolean correcto = this.modificarEdificio(edificio,urlConfig);
  						
    				/**
					 * Si la creación / modificación es correcta, se crea o modifica el Activo 
					 * correspondiente al edificio
					 */
					if(correcto){
						String urlActivos = urlConfig+"Expertis_Sync_Movil_JS/index.php/sync/masters/SubirActivos/";
						
	   					
						String randomUUIDString = "";
	   					if(edificio.getGuidedificio() != null && !edificio.getGuidedificio().trim().equals("")){
	   						randomUUIDString = edificio.getGuidedificio();
	   					}
	   					int idZona = 0;
	   					if(edificio.getIdterri() != null && edificio.getIdterri() != 0){
	   						idZona = edificio.getIdterri();
	   					}
	   					java.util.Date fechaActual = new Date();
	   					DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	   					String fechaActualJson = df.format(fechaActual);
	   					
						JSONArray listaActivoCliente = new JSONArray();
	   					JSONObject activoCliente = new JSONObject();
	   					activoCliente.put("DescActivo", edificio.getEedificio() + " / " + edificio.getCedificio());
	   					activoCliente.put("NSerie",JSONObject.NULL);
	   					activoCliente.put("IdCliente",edificio.getIdedificio());
	   					activoCliente.put("IdClaseActivo","AA20BEDIF");
	   					activoCliente.put("IdZona",idZona);
	   					activoCliente.put("QR",JSONObject.NULL);
	   					activoCliente.put("Direccion",JSONObject.NULL);
	   					activoCliente.put("CodigoPostal",JSONObject.NULL);
	   					activoCliente.put("Poblacion",JSONObject.NULL);
	   					activoCliente.put("Provincia",JSONObject.NULL);
	   					activoCliente.put("PosicionGPS",JSONObject.NULL);
	   					activoCliente.put("CodEnlace",JSONObject.NULL);
	   					activoCliente.put("IdActivo","ACT"+edificio.getIdedificio());
	   					activoCliente.put("IdEstado",JSONObject.NULL);
	   					activoCliente.put("Pais",JSONObject.NULL);
	   					activoCliente.put("IdAgrupacionActivo",JSONObject.NULL);
	   					activoCliente.put("FechaFinGarantia",JSONObject.NULL);
	   					activoCliente.put("fechaSincronizacion",fechaActualJson);
	   					activoCliente.put("fechaActual", fechaActualJson);
	   					activoCliente.put("FechaUltimaSinc",fechaActualJson);
	   					// Si se ha puesto de baja metemos la fecha de baja
	   					if (edificio.getBaja() != null && edificio.getBaja().equals("1")) {
	   						activoCliente.put("FechaBaja", fechaActualJson);
	   					} else {
	   						activoCliente.put("FechaBaja", JSONObject.NULL);
	   					}
	   					
	   					
	   					activoCliente.put("UUIdActivo",randomUUIDString);
	   					listaActivoCliente.put(activoCliente);
	   					
	   					JSONArray listaActivoCampo = new JSONArray();
	   					JSONObject activoCampoC = new JSONObject();
	   					activoCampoC.put("UUIDActivo",randomUUIDString);
	   					activoCampoC.put("Valor",edificio.getCedificio());
	   					activoCampoC.put("IdCampo","CEDIFICIO");
	   					JSONObject activoCampoE = new JSONObject();
	   					activoCampoE.put("UUIDActivo",randomUUIDString);
	   					activoCampoE.put("Valor",edificio.getEedificio());
	   					activoCampoE.put("IdCampo","EEDIFICIO");
	   					listaActivoCampo.put(activoCampoC);
	   					listaActivoCampo.put(activoCampoE);
	   	   					
						JSONObject activos = new JSONObject();
						activos.put("activos", listaActivoCliente);
						activos.put("activosPreventivo",JSONObject.NULL);
						activos.put("activoCampo",listaActivoCampo);
						
						String jsonRequestDataActivos = activos.toString();
						Aa20bProcessMessage.logger.info(jsonRequestDataActivos);
	   						
						String respuestaActivos = sincronizarDatosGmao(urlActivos, jsonRequestDataActivos);
						
						if(respuestaActivos != null){
							JSONObject respActivos = new JSONObject(respuestaActivos);
							Aa20bProcessMessage.logger.info("Resp " + respActivos);       

							String resActivos = respActivos.get("respuesta").toString();
							if (resActivos != null && resActivos.equals("ERROR")) {
								String codigo = respActivos.get("codigo").toString();
								String mensaje = respActivos.get("mensaje").toString();
								String msgError = "Error en la sincronización con Gmao: " + codigo
									+ ": " + mensaje;
								this.enviaMensajeErrorGmao(msgError);
							} else if (resActivos != null && resActivos.equals("INFO")) {
								String mensaje = respActivos.get("mensaje").toString();
								
							}
						}
					}
    				
    				break;
    				
    			}
    			case Aa20bConstantes.OPER_MANT_TECNICO:{
    				
    				com.ejie.aa20b.model.Tecnicos tecnico = (com.ejie.aa20b.model.Tecnicos) ((ObjectMessage)message).getObject();
    				
    				String urlConfig = Aa20bParametros.get("movilgmao.path");
    				
    				boolean correcto = this.modificarTecnico(tecnico, urlConfig);
  						
    				/**
					 * Si la creación / modificación es correcta, se crea o modifica el Activo 
					 * correspondiente al edificio
					 */
					/*if(correcto){
						String urlActivos = "http://svc.intra.integracion.jakina.ejiedes.net/ctxapp/aa20bWebServices/Expertis_Sync_Movil_JS/index.php/sync/masters/SubirActivos/";
						
	   					
						String randomUUIDString = "";
	   					if(tecnico.getGuidtecnico() != null && !tecnico.getGuidtecnico().trim().equals("")){
	   						randomUUIDString = tecnico.getGuidtecnico();
	   					}
	   					int idZona = 0;
	   					
	   					java.util.Date fechaActual = new Date();
	   					DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	   					String fechaActualJson = df.format(fechaActual);
	   					
						JSONArray listaActivoOperario = new JSONArray();
	   					JSONObject activoOperario = new JSONObject();
	   					activoOperario.put("DescActivo", tecnico.getNombre());
	   					activoOperario.put("NSerie",JSONObject.NULL);
	   					activoOperario.put("IdCliente","880000");
	   					activoOperario.put("IdClaseActivo","AA20BEDIF");
	   					activoOperario.put("IdZona",idZona);
	   					activoOperario.put("QR",JSONObject.NULL);
	   					activoOperario.put("Direccion",JSONObject.NULL);
	   					activoOperario.put("CodigoPostal",JSONObject.NULL);
	   					activoOperario.put("Poblacion",JSONObject.NULL);
	   					activoOperario.put("Provincia",JSONObject.NULL);
	   					activoOperario.put("PosicionGPS",JSONObject.NULL);
	   					activoOperario.put("CodEnlace",JSONObject.NULL);
	   					activoOperario.put("IdActivo","ACT"+tecnico.getIdtecnico());
	   					activoOperario.put("IdEstado",JSONObject.NULL);
	   					activoOperario.put("Pais",JSONObject.NULL);
	   					activoOperario.put("IdAgrupacionActivo",JSONObject.NULL);
	   					activoOperario.put("FechaFinGarantia",JSONObject.NULL);
	   					activoOperario.put("fechaSincronizacion",fechaActualJson);
	   					activoOperario.put("fechaActual", fechaActualJson);
	   					activoOperario.put("FechaUltimaSinc",fechaActualJson);
	   					// Si se ha puesto de baja metemos la fecha de baja
	   					if (tecnico.getBaja() != null && tecnico.getBaja().equals("1")) {
	   						activoOperario.put("FechaBaja", fechaActualJson);
	   					} else {
	   						activoOperario.put("FechaBaja", JSONObject.NULL);
	   					}
	   					
	   					
	   					activoOperario.put("UUIdActivo",randomUUIDString);
	   					listaActivoOperario.put(activoOperario);
	   					
	   					JSONArray listaActivoCampo = new JSONArray();
	   					JSONObject activoCampoC = new JSONObject();
	   					activoCampoC.put("UUIDActivo",randomUUIDString);
	   					activoCampoC.put("Valor",tecnico.getNombre());
	   					activoCampoC.put("IdCampo","NOMBRE");
	   					listaActivoCampo.put(activoCampoC);
	   					
	   	   					
						JSONObject activos = new JSONObject();
						activos.put("activos", listaActivoOperario);
						activos.put("activosPreventivo",JSONObject.NULL);
						activos.put("activoCampo",listaActivoCampo);
						
						String jsonRequestDataActivos = activos.toString();
						Aa20bProcessMessage.logger.info(jsonRequestDataActivos);
	   						
						String respuestaActivos = sincronizarDatosGmao(urlActivos, jsonRequestDataActivos);
						
						if(respuestaActivos != null){
							JSONObject respActivos = new JSONObject(respuestaActivos);
							Aa20bProcessMessage.logger.info("Resp " + respActivos);       

							String resActivos = respActivos.get("respuesta").toString();
							if (resActivos != null && resActivos.equals("ERROR")) {
								String codigo = respActivos.get("codigo").toString();
								String mensaje = respActivos.get("mensaje").toString();
								String msgError = "Error en la sincronización con Gmao: " + codigo
									+ ": " + mensaje;
								this.enviaMensajeErrorGmao(msgError);
							} else if (resActivos != null && resActivos.equals("INFO")) {
								String mensaje = respActivos.get("mensaje").toString();
								
							}
						}
					}*/
    				
    				break;
    				
    			}
    			case Aa20bConstantes.OPER_MANT_LINEAS_ENTIDADES:{
    				String urlConfig = Aa20bParametros.get("movilgmao.path");
    				String urlEntidad = urlConfig+Aa20bConstantes.URL_LINEAS_ENTIDAD;
    				
    				String jsonRequestDataEntidad = ((TextMessage)message).getText() ;
    				Aa20bProcessMessage.logger.info(jsonRequestDataEntidad);
						
					String respuestaEntidad = sincronizarDatosGmao(urlEntidad, jsonRequestDataEntidad);
					
					if(respuestaEntidad != null){
						JSONObject respEntidad = new JSONObject(respuestaEntidad);
						Aa20bProcessMessage.logger.info("Resp " + respEntidad);       

						String resEntidad = respEntidad.get("respuesta").toString();
						if (resEntidad != null && resEntidad.equals("ERROR")) {
							String codigo = respEntidad.get("codigo").toString();
							String mensaje = respEntidad.get("mensaje").toString();
							String msgError = "Error en la sincronización con Gmao: " + codigo
								+ ": " + mensaje;
							this.enviaMensajeErrorGmao(msgError);
						} else if (resEntidad != null && resEntidad.equals("INFO")) {
							String mensaje = respEntidad.get("mensaje").toString();
						}
					}
    				break;
    				
    			}
    			case Aa20bConstantes.OPER_MANT_ENUMERADOS:{
    				String urlConfig = Aa20bParametros.get("movilgmao.path");
    				String urlEntidad = urlConfig+Aa20bConstantes.URL_SUBIR_ENUMERADOS;
    				
    				String jsonRequestDataEnumerados = ((TextMessage)message).getText() ;
    				Aa20bProcessMessage.logger.info(jsonRequestDataEnumerados);
						
					String respuestaEnumerados = sincronizarDatosGmao(urlEntidad, jsonRequestDataEnumerados);
					
					if(respuestaEnumerados != null){
						JSONObject respEnum = new JSONObject(respuestaEnumerados);
						Aa20bProcessMessage.logger.info("Resp " + respEnum);       

						String resEnumerado = respEnum.get("respuesta").toString();
						if (resEnumerado != null && resEnumerado.equals("ERROR")) {
							String codigo = respEnum.get("codigo").toString();
							String mensaje = respEnum.get("mensaje").toString();
							String msgError = "Error en la sincronización con Gmao: " + codigo
								+ ": " + mensaje;
							this.enviaMensajeErrorGmao(msgError);
						} else if (resEnumerado != null && resEnumerado.equals("INFO")) {
							String mensaje = respEnum.get("mensaje").toString();
						}
					}
    				break;
    			}
    			default:{
    				break;
    			}
    		}
    	}catch(JMSException jmse){
    		Aa20bProcessMessage.logger.error("JMS Excepcion " + jmse.getMessage());
    		jmse.printStackTrace();
    		context.setRollbackOnly();
    	}
    	catch(Exception e){
    		Aa20bProcessMessage.logger.error("Excepcion general POST Gmao: " + e.toString());
    		e.printStackTrace();
    		context.setRollbackOnly();
    	}
    	catch(Throwable t){
    		Aa20bProcessMessage.logger.error("JMS Excepcion " + t.getMessage());
    		t.printStackTrace();
    		context.setRollbackOnly();
    	}
		
		
	}
	
	private boolean modificarEdificio(com.ejie.aa20b.model.Edificios edificio, String urlConfig) throws JMSException, Exception{
		boolean correcto = true;
		
		
		
		/**
		 * Se modifica clientes (edificios) de la BBDD de gmao
		 */
		String url = urlConfig+"Expertis_Sync_Movil_JS/index.php/sync/masters/SubirClientesSinBorrar/";
			
		JSONArray listaEdificios = new JSONArray();
		JSONObject edificio1 = new JSONObject();
		edificio1.put("IdCliente", edificio.getIdedificio());
		edificio1.put("DescCliente", edificio.getEedificio() + " / " + edificio.getCedificio());
		listaEdificios.put(edificio1);
					
		JSONObject clientes = new JSONObject();
		clientes.put("clientes", listaEdificios);
		String jsonRequestData = clientes.toString();
		Aa20bProcessMessage.logger.info(jsonRequestData);
				
		String respuesta = this.sincronizarDatosGmao(url, jsonRequestData);
				
		if(respuesta != null){
			JSONObject resp = new JSONObject(respuesta);
			Aa20bProcessMessage.logger.info("Resp " + resp);       

			String res = resp.get("respuesta").toString();
			if (res != null && res.equals("ERROR")) {
				correcto = false;
				String codigo = resp.get("codigo").toString();
				String mensaje = resp.get("mensaje").toString();
				String msgError = "Error en la sincronización con Gmao: " + codigo
					+ ": " + mensaje;
				this.enviaMensajeErrorGmao(msgError);
			} else if (res != null && res.equals("INFO")) {
				String mensaje = resp.get("mensaje").toString();
				
			}
		}else{
			correcto = false;
		}
		
		
		return correcto;
	}
	
	private boolean modificarTecnico(com.ejie.aa20b.model.Tecnicos tecnico, String urlConfig) throws JMSException, Exception{
boolean correcto = true;
		
		/**
		 * Se modifica operarios (técnicos) de la BBDD de gmao
		 */
		String url = urlConfig+"Expertis_Sync_Movil_JS/index.php/sync/masters/SubirOperariosSinBorrar/";
			
		JSONArray listaTecnicos = new JSONArray();
		JSONObject tecnico1 = new JSONObject();
		tecnico1.put("IdOperario", tecnico.getIdtecnico());
		tecnico1.put("DescOperario", tecnico.getNombre());
		listaTecnicos.put(tecnico1);
					
		JSONObject clientes = new JSONObject();
		clientes.put("operarios", listaTecnicos);
		String jsonRequestData = clientes.toString();
		Aa20bProcessMessage.logger.info(jsonRequestData);
				
		String respuesta = this.sincronizarDatosGmao(url, jsonRequestData);
				
		if(respuesta != null){
			JSONObject resp = new JSONObject(respuesta);
			Aa20bProcessMessage.logger.info("Resp " + resp);       

			String res = resp.get("respuesta").toString();
			if (res != null && res.equals("ERROR")) {
				correcto = false;
				String codigo = resp.get("codigo").toString();
				String mensaje = resp.get("mensaje").toString();
				String msgError = "Error en la sincronización con Gmao: " + codigo
					+ ": " + mensaje;
				this.enviaMensajeErrorGmao(msgError);
			} else if (res != null && res.equals("INFO")) {
				String mensaje = resp.get("mensaje").toString();
				
			}
		}else{
			correcto = false;
		}
		
		
		return correcto;
	}
	
	private String sincronizarDatosGmao(String url, String jsonRequestData) throws Exception{
		org.apache.http.client.methods.CloseableHttpResponse response = null;
		String respuesta = "";
		
			
		SSLContextBuilder builderList = new SSLContextBuilder();
		builderList.loadTrustMaterial(null, new TrustSelfSignedStrategy());
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
				builderList.build());
		
		String usuarioGmao = "";

		try {
			if (url != null
					&& !url.equals("")
					&& (url.indexOf("ejiedes") != -1 || url
							.indexOf("ejiepru") != -1)) {
				usuarioGmao = Aa20bParametros.get("movilgmaodesa.user");
			} else {
				usuarioGmao = Aa20bParametros.get("movilgmaopro.user");
			}

		} catch (Exception e) {

		}

		org.apache.http.client.methods.HttpPost httpPost = null;
		HttpClientBuilder clientBuilder = HttpClientBuilder.create(); 
		clientBuilder.setSSLSocketFactory(sslsf);
		CloseableHttpClient httpClient = clientBuilder.build(); 
   
		httpPost = new HttpPost(url);
		httpPost.addHeader(
				"Authorization",
				"Basic "
				+ new String(Base64.encodeBase64((usuarioGmao).getBytes())));
		httpPost.addHeader("content-type", "application/json;charset=UTF-8");
	
		StringEntity se = new StringEntity(jsonRequestData,
				ContentType.create("text/plain", "UTF-8"));
		httpPost.setEntity(se);
		httpPost.setHeader("Content-Type",
		"application/json;charset=UTF-8");
		httpPost.setHeader("Accept-Encoding", "application/json");
		response = httpClient.execute(httpPost);
   	 
		HttpEntity entityList = response.getEntity();
           
		if (response.getStatusLine().getStatusCode() != 200) {
			Aa20bProcessMessage.logger.error("Conexión inccorrecta:" + response.getStatusLine().getStatusCode());
			
				throw new JMSException("Conexión inccorrecta : "
						+ response.getStatusLine().getStatusCode());
		}
		Aa20bProcessMessage.logger.info("Conexión correcta:" + response.getStatusLine().getStatusCode());
  	
		respuesta = EntityUtils.toString(entityList);
          
		EntityUtils.consume(entityList);
		
		response.close();
			
		return respuesta;
	}
	
	
	private void enviaMensajeErrorJMS() throws JMSException {
       	Session session = jmsConnection.createSession(true,
               Session.AUTO_ACKNOWLEDGE);
       	MessageProducer producer = session.createProducer(errorQueue);
       	producer.send(message);
       	session.close();

    }
	
	private void enviaMensajeErrorGmao(String msgErrorResp) throws JMSException{
		Session session = jmsConnection.createSession(true,
               Session.AUTO_ACKNOWLEDGE);
       	MessageProducer producer = session.createProducer(errorQueue);
       	TextMessage messagetext = session.createTextMessage(msgErrorResp);
       	producer.send(messagetext);
       	session.close();
	}
	

}
