package com.ejie.ab04b.service.eventos;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ejie.ab04b.constantes.Constantes;
import com.ejie.ab04b.model.eventos.ErrorEventoCola;

/**
 * Servicios para tratamiento de los avisos que vienen desde sistemas externos
 * al sistema. Esta implementacion deriva los mensajes en primera a instancia a
 * base de datos, y en caso de error a un fichero de texto
 * 
 * @author GFI(SGG)
 * 
 */
@Service(value = "deadMessageService")
public class DeadMessageImpl implements DeadMessageService {
	/** Sistema de trazas del objeto */
	private static final Logger LOGGER = LoggerFactory.getLogger(DeadMessageImpl.class);
	@Autowired()
	private ErrorEventoColaService errorEventoColaService;

	/* (non-Javadoc)
	 * @see com.ejie.ab04b.service.eventos.DeadMessageService#tratarDeadMessage(java.lang.String, javax.jms.Message)
	 */
	@Override()
	public boolean tratarDeadMessage(String origen, Message message) {

		boolean mensajeTratado = false;
		DeadMessageImpl.LOGGER.info("tratarDeadMessage: Inicio");
		ErrorEventoCola errorEventoCola = new ErrorEventoCola();
		errorEventoCola.setTipoproc(origen);
		try {
			errorEventoCola.setEvento(((TextMessage) message).getText());
			this.errorEventoColaService.add(errorEventoCola);
			mensajeTratado = true;
		} catch (Exception th) {
			// cogemos th porque pase lo que pase queremos intentar serializar
			// aunque sea en fichero
			DeadMessageImpl.LOGGER.error("tratarDeadMessage: no se ha podido almacenar el evento en BD", th);
			// intentamos almacenar el mensaje en BD
			// si no ha funcionado intentamos almacenar el mensaje en fichero
			if (message instanceof TextMessage) {
				try {
					mensajeTratado = this.escribirMensajeTextoAFichero(((TextMessage) message).getText(),
							Constantes.DEAD_MESSAGES_INTERFAZ_FILE, "[#INICIO_TRACEO_MENSAJE#]",
							"[#FIN_TRACEO_MENSAJE#]");
				} catch (JMSException jmse) {
					DeadMessageImpl.LOGGER.error("escribirMensajeAFichero: error al convertir el mensaje a texto",
							jmse);
					mensajeTratado = this.escribirMensajeTextoAFichero(message.toString(),
							Constantes.DEAD_MESSAGES_INTERFAZ_FILE, "[#INICIO_TRACEO_MENSAJE_NTXT#]",
							"[#FIN_TRACEO_MENSAJE_NTXT#]");

				}
			} else {
				mensajeTratado = this.escribirMensajeTextoAFichero(message.toString(),
						Constantes.DEAD_MESSAGES_INTERFAZ_FILE, "[#INICIO_TRACEO_MENSAJE_NTXT#]",
						"[#FIN_TRACEO_MENSAJE_NTXT#]");
			}

		}
		DeadMessageImpl.LOGGER.info("tratarDeadMessage: Fin");
		return mensajeTratado;
	}

	/**
	 * Escribe un texto en un fichero de error
	 * 
	 *  texto
	 *            mensaje a escribir
	 *  ruta
	 *            ruta del fichero en la que se debe escribir
	 *  separadorInicio
	 *            separador a utilizar antes del mensaje, puede ser null
	 *  separadorFin
	 *            separador a utilizar despues del mensaje, puede ser null
	 * 
	 *  true si ha podido finalizar el tratamiento del mensaje, false en
	 *         caso contrario.
	 *
	 * @param texto the texto
	 * @param ruta the ruta
	 * @param separadorInicio the separador inicio
	 * @param separadorFin the separador fin
	 * @return true, if successful
	 */
	private synchronized boolean escribirMensajeTextoAFichero(String texto, String ruta, String separadorInicio,
			String separadorFin) {
		DeadMessageImpl.LOGGER.info("escribirMensajeTextoAFichero: Inicio");
		boolean mensajeTratado = false;
		File fichero = new File(ruta);
		BufferedWriter bufferedWriter = null;
		try {
			if (!fichero.exists()) {
				// el fichero no existe. hay que crearlo
				fichero.createNewFile();
			}
			bufferedWriter = new BufferedWriter(new FileWriter(fichero, true));
			bufferedWriter.newLine();
			if (null != separadorInicio) {
				bufferedWriter.write(separadorInicio);
			}
			bufferedWriter.newLine();
			bufferedWriter.write(texto);
			if (null != separadorFin) {
				bufferedWriter.write(separadorFin);
			}
			bufferedWriter.newLine();
			bufferedWriter.flush();
			mensajeTratado = true;
		} catch (IOException ioe) {
			DeadMessageImpl.LOGGER.error("escribirMensajeTextoAFichero: error de acceso al fichero ", ioe);
		} finally {
			if (bufferedWriter != null) {
				try {
					bufferedWriter.close();
				} catch (IOException ioe) {
					DeadMessageImpl.LOGGER.error("escribirMensajeTextoAFichero: error al cerrar el fichero ", ioe);
				}
			}
		}
		DeadMessageImpl.LOGGER.info("escribirMensajeTextoAFichero: Fin");
		return mensajeTratado;
	}
}
