package com.ejie.ab04b.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.text.SimpleDateFormat;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ejie.ab04b.constantes.ConstantesDocumentos;
import com.ejie.ab04b.exception.AB04BException;
import com.ejie.ab04b.model.VdocOs4;
import com.ejie.ab04b.util.CaracteresRarosUtil;
import com.ejie.ab04b.util.Utilities;

@Service(value = "generacionPDFDocOS4Impl")
public class GeneracionPDFDocOS4Impl implements GeneracionPDFDocOS4Service {

	@Autowired
	private VdocOs4Service vdocOs4Service;

	/**
	 * Devuelve un InputStream con el documento pdf.
	 * 
	 *  folderNumber
	 *            String
	 *  numEje
	 *            Integer
	 *  Inputstream
	 *
	 * @param folderNumber the folder number
	 * @param numEje the num eje
	 * @return the pdf
	 * @throws AB04BException the AB 04 B exception
	 */
	public InputStream getPDF(String folderNumber, Integer numEje)
			throws AB04BException {
		String folderNumberAux = folderNumber;
		try {
			folderNumberAux = folderNumberAux.replaceAll("/", "-");
			String xslFichero = "";
			xslFichero = ConstantesDocumentos.DOC_OS4_XSL;

			InputStream inputStream = null;

			VdocOs4 vdocOs4 = new VdocOs4(folderNumberAux);
			vdocOs4.setNumeje(numEje);
			vdocOs4 = this.vdocOs4Service.find(vdocOs4);
			StringBuffer xmlPdf = getXml(vdocOs4);
			String xml = CaracteresRarosUtil.htmlEscape(xmlPdf.toString());
			StringReader lxmlReader = new StringReader(xml);
			// Inicializo transformer
			Transformer transformer = pdfTransformacionInit(xslFichero);
			// Ejecuto transformación
			ByteArrayOutputStream byteOut = pdfTransformacionExec(transformer,
					lxmlReader, org.apache.fop.apps.Driver.RENDER_PDF);

			byte[] bytes = byteOut.toByteArray();
			inputStream = new ByteArrayInputStream(bytes);

			byteOut.close();

			return inputStream;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Inicializa la transformacion a PDF.
	 * 
	 *  xslFichero
	 *            String
	 *  Transformer
	 *
	 * @param xslFichero the xsl fichero
	 * @return the transformer
	 * @throws AB04BException the AB 04 B exception
	 */
	private Transformer pdfTransformacionInit(String xslFichero)
			throws AB04BException {
		try {
			TransformerFactory tFactory = TransformerFactory.newInstance();
			// org.apache.fop.configuration.Configuration.put("baseDir", "c:/");
			return tFactory.newTransformer(new StreamSource(xslFichero));
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Ejecuta la transformación PDF.
	 * 
	 *  transformer
	 *            transformer
	 *  strReader
	 *            strReader
	 *  renderer
	 *            renderer
	 *  ByteArrayOutputStream
	 *
	 * @param transformer the transformer
	 * @param strReader the str reader
	 * @param renderer the renderer
	 * @return the byte array output stream
	 * @throws AB04BException the AB 04 B exception
	 */
	private ByteArrayOutputStream pdfTransformacionExec(
			Transformer transformer, StringReader strReader, int renderer)
			throws AB04BException {
		try {

			DOMResult domResultado = new DOMResult();

			transformer.transform(new StreamSource(strReader), domResultado);

			org.apache.fop.apps.Driver driver = new org.apache.fop.apps.Driver();

			driver.setRenderer(renderer);

			ByteArrayOutputStream byteOut = new ByteArrayOutputStream();

			driver.setOutputStream(byteOut);
			driver.render((org.w3c.dom.Document) domResultado.getNode());
			driver.reset();

			return byteOut;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Obtiene los datos y genera el XML.
	 * 
	 *  vdocOs4
	 *            VdocOs4
	 *  StringBuffer
	 *
	 * @param vdocOs4 the vdoc os 4
	 * @return the xml
	 * @throws AB04BException the AB 04 B exception
	 */
	private StringBuffer getXml(VdocOs4 vdocOs4) throws AB04BException {
		try {
			String mascara = Utilities.getInstance().getDateMask();
			SimpleDateFormat sdf = new SimpleDateFormat(mascara);

			StringBuffer xml = new StringBuffer();
			xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			xml.append("<docOS4>");
			xml.append("<direccion>");
			xml.append((vdocOs4.getDireccion() != null) ? sustituirCaracteres(vdocOs4
					.getDireccion()) : "");
			xml.append("</direccion>");
			xml.append("<codPro>");
			xml.append("");
			xml.append("</codPro>");
			xml.append("<promotor>");
			xml.append((vdocOs4.getPromotor() != null) ? sustituirCaracteres(vdocOs4
					.getPromotor()) : "");
			xml.append("</promotor>");
			xml.append("<contrata>");
			xml.append((vdocOs4.getContrata() != null) ? sustituirCaracteres(vdocOs4
					.getContrata()) : "");
			xml.append("</contrata>");
			xml.append("<avisoSi>");
			xml.append((vdocOs4.getAvisosi() != null) ? sustituirCaracteres(vdocOs4
					.getAvisosi()) : "");
			xml.append("</avisoSi>");
			xml.append("<avisoNo>");
			xml.append((vdocOs4.getAvisono() != null) ? sustituirCaracteres(vdocOs4
					.getAvisono()) : "");
			xml.append("</avisoNo>");
			xml.append("<comunicacionSi>");
			xml.append((vdocOs4.getComunicacionsi() != null) ? sustituirCaracteres(vdocOs4
					.getComunicacionsi()) : "");
			xml.append("</comunicacionSi>");
			xml.append("<comunicacionNo>");
			xml.append((vdocOs4.getComunicacionno() != null) ? sustituirCaracteres(vdocOs4
					.getComunicacionno()) : "");
			xml.append("</comunicacionNo>");
			xml.append("<planSi>");
			xml.append((vdocOs4.getPlansi() != null) ? sustituirCaracteres(vdocOs4
					.getPlansi()) : "");
			xml.append("</planSi>");
			xml.append("<planNo>");
			xml.append((vdocOs4.getPlanno() != null) ? sustituirCaracteres(vdocOs4
					.getPlanno()) : "");
			xml.append("</planNo>");
			xml.append("<fecha>");
			xml.append((vdocOs4.getFecha() != null) ? sustituirCaracteres(sdf
					.format(vdocOs4.getFecha())) : "");
			xml.append("</fecha>");
			xml.append("<nombreEmpresa>");
			xml.append((vdocOs4.getNombreempresa() != null) ? sustituirCaracteres(vdocOs4
					.getNombreempresa()) : "");
			xml.append("</nombreEmpresa>");
			xml.append("<promo>");
			xml.append((vdocOs4.getPromo() != null) ? sustituirCaracteres(vdocOs4
					.getPromo()) : "");
			xml.append("</promo>");
			xml.append("<con>");
			xml.append((vdocOs4.getCon() != null) ? sustituirCaracteres(vdocOs4
					.getCon()) : "");
			xml.append("</con>");
			xml.append("<subcon>");
			xml.append((vdocOs4.getSubcon() != null) ? sustituirCaracteres(vdocOs4
					.getSubcon()) : "");
			xml.append("</subcon>");
			xml.append("<aut>");
			xml.append((vdocOs4.getAut() != null) ? sustituirCaracteres(vdocOs4
					.getAut()) : "");
			xml.append("</aut>");
			xml.append("<nomRes1>");
			xml.append((vdocOs4.getNomres1() != null) ? sustituirCaracteres(vdocOs4
					.getNomres1()) : "");
			xml.append("</nomRes1>");
			xml.append("<nomRes2>");
			xml.append((vdocOs4.getNomres2() != null) ? sustituirCaracteres(vdocOs4
					.getNomres2()) : "");
			xml.append("</nomRes2>");
			xml.append("<desRes1>");
			xml.append((vdocOs4.getDesres1() != null) ? sustituirCaracteres(vdocOs4
					.getDesres1()) : "");
			xml.append("</desRes1>");
			xml.append("<desRes2>");
			xml.append((vdocOs4.getDesres2() != null) ? sustituirCaracteres(vdocOs4
					.getDesres2()) : "");
			xml.append("</desRes2>");
			xml.append("<nomRep>");
			xml.append((vdocOs4.getNomrep() != null) ? sustituirCaracteres(vdocOs4
					.getComunicacionno()) : "");
			xml.append("</nomRep>");
			xml.append("<representacion>");
			xml.append((vdocOs4.getRepresentacion() != null) ? sustituirCaracteres(vdocOs4
					.getRepresentacion()) : "");
			xml.append("</representacion>");
			xml.append("<codCau01>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau01>");
			xml.append("<codCau02>");
			xml.append((vdocOs4.getCodcau02() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau02()) : "");
			xml.append("</codCau02>");
			xml.append("<codCau03>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau03>");
			xml.append("<codCau04>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau04>");
			xml.append("<codCau05>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau05>");
			xml.append("<codCau06>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau06>");
			xml.append("<codCau07>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau07>");
			xml.append("<codCau08>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau08>");
			xml.append("<codCau09>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau09>");
			xml.append("<codCau10>");
			xml.append((vdocOs4.getCodcau01() != null) ? sustituirCaracteres(vdocOs4
					.getCodcau01()) : "");
			xml.append("</codCau10>");
			xml.append("<observaciones>");
			xml.append((vdocOs4.getObservaciones() != null) ? sustituirCaracteres(vdocOs4
					.getObservaciones()) : "");
			xml.append("</observaciones>");
			xml.append("<coordinador>");
			xml.append((vdocOs4.getCoordinador() != null) ? sustituirCaracteres(vdocOs4
					.getCoordinador()) : "");
			xml.append("</coordinador>");
			xml.append("<expediente>");
			xml.append((vdocOs4.getExpediente() != null) ? sustituirCaracteres(vdocOs4
					.getExpediente().toString()) : "");
			xml.append("</expediente>");
			xml.append("</docOS4>");
			return xml;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Obtiene los datos y genera el XML.
	 * 
	 *  cadena
	 *            String
	 *  String
	 *
	 * @param cadena the cadena
	 * @return the string
	 * @throws AB04BException the AB 04 B exception
	 */
	private static String sustituirCaracteres(String cadena)
			throws AB04BException {
		try {
			String cadenaSustituida = cadena;

			if (cadenaSustituida != null && cadenaSustituida.indexOf("<") != -1) {
				cadenaSustituida = cadenaSustituida.replaceAll("<", "MENOS DE");
			} else if (cadenaSustituida != null
					&& cadenaSustituida.indexOf(">") != -1) {
				cadenaSustituida = cadenaSustituida.replaceAll(">", "MAYOR DE");
			}
			return cadenaSustituida;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}
}
