package com.ejie.ad74a.ws.server.televida.service;

import java.util.HashMap;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ejie.ad74a.exceptions.Ad74aException;
import com.ejie.ad74a.model.ErroresTelevida;
import com.ejie.ad74a.scheduler.JobSchedulerService;
import com.ejie.ad74a.scheduler.SchedulerJobType;
import com.ejie.ad74a.service.ErroresTelevidaService;
import com.ejie.ad74a.util.comun.UtilidadesXML;
import com.ejie.ad74a.util.constantes.RespuestasTelevidaEnum;
import com.ejie.ad74a.ws.server.televida.model.Comunicacion;
import com.ejie.ad74a.ws.server.televida.model.Respuesta;
import com.ejie.ad74a.ws.server.televida.util.ModelApplicationParser;

@Service(value = "TelevidaProccesService")
public class TelevidaProccesServiceImpl implements TelevidaProccesService {

	/**
	 * Final static logger.
	 */
	private static final Logger logger = LoggerFactory.getLogger(TelevidaProccesServiceImpl.class);

	@Autowired
	private ErroresTelevidaService erroresTelevidaService;

	@Autowired
	private TelevidaService televidaService;

	@Autowired
	private JobSchedulerService jobSchedulerService;

	/**
	 * Procesar la validación inicial de la petición
	 * 
	 * @param Comunicacion comunicacion
	 * @return Respuesta
	 */
	public Respuesta proccesMessage(Comunicacion comunicacion) throws Throwable {
		TelevidaProccesServiceImpl.logger.info("TelevidaProccesServiceImpl.proccesMessage - Inicio");
		Respuesta respuesta = null;
		String idPeticion = "";
		try {
			respuesta = this.televidaService.initialValidationComunication(comunicacion);
			idPeticion = comunicacion.getCabecera().getIdPeticion();
		} catch (Throwable e) {
			respuesta = new Respuesta();
			respuesta = RespuestasTelevidaEnum.ERROR_GENERICO.getRespuesta();
			respuesta.setMensaje(e.getMessage());
			respuesta.setIdPeticion(idPeticion);
			TelevidaProccesServiceImpl.logger.error("Error procesar evento: " + e.getMessage());

			// guardamos el mensaje de error
			ErroresTelevida comunicationError = ModelApplicationParser.getComunicationToError(comunicacion);
			if (e instanceof Ad74aException) {
				Ad74aException ex = (Ad74aException) e;
				comunicationError.setErrormsg51(getErrorMessage(ex.getMessage()));
				comunicationError.setError51(ex.getCodeError());
				TelevidaProccesServiceImpl.logger.error("Error procesar evento: " + ex.getMessage());
			} else {
				comunicationError.setErrormsg51(getErrorMessage(ExceptionUtils.getStackTrace(e)));
				TelevidaProccesServiceImpl.logger.error("Error procesar evento: " + ExceptionUtils.getStackTrace(e));
			}

			// Para controlar el reintentar ponemos un código de error concreto
			comunicationError.setError51("VALIDACION");
			comunicationError.setMensaje51(UtilidadesXML.marshalObjectWS(comunicacion));
			comunicationError = erroresTelevidaService.add(comunicationError);

			try {
				// ** Programar RE-Ejecución en diferido ** //
				HashMap<String, String> params = new HashMap<String, String>();
				params.put("id", comunicationError.getIdError51().toString());
				this.jobSchedulerService.programarEjecucion(SchedulerJobType.ERROR_TELEVIDA, params);
			} catch (Exception e2) {
				// Solo para que no haga rollback
				TelevidaProccesServiceImpl.logger
						.error("Error programando re-ejecución: " + ExceptionUtils.getStackTrace(e2));
			}
		}
		TelevidaProccesServiceImpl.logger.info("TelevidaProccesServiceImpl.proccesMessage - Fin");
		return respuesta;
	}

//	public String proccesMessage(Comunicacion comunicacion) throws Throwable {
//		String message = "";
//		TelevidaProccesServiceImpl.logger.info("TelevidaProccesServiceImpl.proccesMessage - Inicio");
//		Respuesta respuesta = null;
//		// glozano ya no hace falta el unmarshall porque llega el objeto Comunicacion
////		try {
////			comunicacion = (Comunicacion) UtilidadesXML.unmarshallerObject(message, Comunicacion.class);
////		} catch (UnmarshalException e) {
////			TelevidaProccesServiceImpl.logger
////					.error("TelevidaProccesServiceImpl.proccesMessage - Error al parsear el mensaje de TELEVIDA " + e);
////		}
//		try {
//			respuesta = this.televidaService.proccesComunication(comunicacion);
//		} catch (Throwable e) {
//			TelevidaProccesServiceImpl.logger.error("Error al tratar la comunicacion de TELEVIDA: ");
//			// guardamos el mensaje de error
//			ErroresTelevida comunicationError = ModelApplicationParser.getComunicationToError(comunicacion);
//			if (e instanceof Ad74aException) {
//				Ad74aException ex = (Ad74aException) e;
//				comunicationError.setErrormsg51(getErrorMessage(ex.getMessage()));
//				comunicationError.setError51(ex.getCodeError());
//				TelevidaProccesServiceImpl.logger.error("Error procesar evento: " + ex.getMessage());
//			} else {
//				comunicationError.setErrormsg51(getErrorMessage(ExceptionUtils.getStackTrace(e)));
//				TelevidaProccesServiceImpl.logger.error("Error procesar evento: " + ExceptionUtils.getStackTrace(e));
//			}
////			comunicationError.setMensaje51(message);
//			comunicationError.setMensaje51(UtilidadesXML.marshalObjectWS(comunicacion));
//			comunicationError = erroresTelevidaDao.add(comunicationError);
//
//			try {
//				// ** Programar RE-Ejecución en diferido ** //
//				HashMap<String, String> params = new HashMap<String, String>();
//				params.put("id", comunicationError.getIdError51().toString());
//				this.jobSchedulerService.programarEjecucion(SchedulerJobType.ERROR_TELEVIDA, params);
//			} catch (Exception e2) {
//				// Solo para que no haga rollback
//				TelevidaProccesServiceImpl.logger
//						.error("Error programando re-ejecución: " + ExceptionUtils.getStackTrace(e2));
//			}
//			respuesta = RespuestasTelevidaEnum.ERROR_EJECUTAR_PROCESO.getRespuesta();
//		}
//		message = UtilidadesXML.marshalObjectWS(respuesta);
//		TelevidaProccesServiceImpl.logger.info("TelevidaProccesServiceImpl.proccesMessage - Fin");
//		return message;
//	}

	private String getErrorMessage(String error) {
		if (null != error && error.length() > 800) {
			error = error.substring(0, 799);
		}
		return error;
	}

//	@Override
//	public String proccesMessage(String message) throws Throwable {
//		// TODO Auto-generated method stub
//		return null;
//	}
}