package com.ejie.ab04b.service;

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

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.VfichaOs3;
import com.ejie.ab04b.util.CaracteresRarosUtil;

@Service(value = "generacionPDFFichaOS3Impl")
public class GeneracionPDFFichaOS3Impl implements GeneracionPDFFichaOS3Service {

	@Autowired
	private VfichaOs3Service vfichaOs3Service;

	/**
	 * Devuelve un InputStream con el documento pdf.
	 * 
	 *  listadoFolderNumber
	 *            String[]
	 *  Inputstream
	 *
	 * @param listadoFolderNumber the listado folder number
	 * @return the pdf
	 * @throws AB04BException the AB 04 B exception
	 */
	public InputStream getPDF(String[] listadoFolderNumber)
			throws AB04BException {
		try {
			String xslFichero = "";
			xslFichero = ConstantesDocumentos.FICHA_OS3_XSL;

			InputStream inputStream = null;

			StringBuffer xmlPdf = getXml(listadoFolderNumber);
			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.
	 * 
	 *  listadoFolderNumber
	 *            String[]
	 *  StringBuffer
	 *
	 * @param listadoFolderNumber the listado folder number
	 * @return the xml
	 * @throws AB04BException the AB 04 B exception
	 */
	private StringBuffer getXml(String[] listadoFolderNumber)
			throws AB04BException {
		try {

			VfichaOs3 vfichaOs3 = new VfichaOs3();

			StringBuffer xml = new StringBuffer();
			xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			xml.append("<impresiones>");

			for (int i = 0; i < listadoFolderNumber.length; i++) {
				vfichaOs3 = obtenerfichaOs3(listadoFolderNumber[i]);
				xml.append("<imprimirOS3>");
				xml.append("<declarante>");
				xml.append((vfichaOs3.getDeclarante() != null) ? vfichaOs3
						.getDeclarante() : "");
				xml.append("</declarante>");
				xml.append("<enCalidadDe>");
				xml.append((vfichaOs3.getEncalidadde() != null) ? vfichaOs3
						.getEncalidadde() : "");
				xml.append("</enCalidadDe>");
				xml.append("<nombreEmpresa>");
				xml.append((vfichaOs3.getNombreempresa() != null) ? vfichaOs3
						.getNombreempresa() : "");
				xml.append("</nombreEmpresa>");
				xml.append("<empresaExistente>");
				xml.append((vfichaOs3.getEmpresaexistente() != null) ? vfichaOs3
						.getEmpresaexistente() : "");
				xml.append("</empresaExistente>");
				xml.append("<empresaNoExistente>");
				xml.append((vfichaOs3.getEmpresanoexistente() != null) ? vfichaOs3
						.getEmpresanoexistente() : "");
				xml.append("</empresaNoExistente>");
				xml.append("<numeroDocumentoEmpresa>");
				xml.append((vfichaOs3.getNumerodocumentoempresa() != null) ? vfichaOs3
						.getNumerodocumentoempresa() : "");
				xml.append("</numeroDocumentoEmpresa>");
				// 20161114 control expediente null
				xml.append("<numeroApertura>");
				xml.append((vfichaOs3.getNumeroapertura() != null) ? vfichaOs3
						.getNumeroapertura() : "");
				xml.append("</numeroApertura>");
				xml.append("<razonSocialEmpresa>");
				xml.append((vfichaOs3.getRazonsocialempresa() != null) ? vfichaOs3
						.getRazonsocialempresa() : "");
				xml.append("</razonSocialEmpresa>");
				xml.append("<direccionEmpresa>");
				xml.append((vfichaOs3.getDireccionempresa() != null) ? vfichaOs3
						.getDireccionempresa() : "");
				xml.append("</direccionEmpresa>");
				xml.append("<municipioEmpresa>");
				xml.append((vfichaOs3.getMunicipioempresa() != null) ? vfichaOs3
						.getMunicipioempresa() : "");
				xml.append("</municipioEmpresa>");
				xml.append("<territorioEmpresa>");
				xml.append((vfichaOs3.getTerritorioempresa() != null) ? vfichaOs3
						.getTerritorioempresa() : "");
				xml.append("</territorioEmpresa>");
				xml.append("<cpEmpresa>");
				xml.append((vfichaOs3.getCpempresa() != null) ? vfichaOs3
						.getCpempresa() : "");
				xml.append("</cpEmpresa>");
				xml.append("<telefonEmpresa>");
				xml.append((vfichaOs3.getTelefonoempresa() != null) ? vfichaOs3
						.getTelefonoempresa() : "");
				xml.append("</telefonEmpresa>");
				xml.append("<emailEmpresa>");
				xml.append((vfichaOs3.getEmaempresa() != null) ? vfichaOs3
						.getEmaempresa() : "");
				xml.append("</emailEmpresa>");
				xml.append("<httpEmpresa>");
				xml.append((vfichaOs3.getHttpempresa() != null) ? vfichaOs3
						.getHttpempresa() : "");
				xml.append("</httpEmpresa>");
				xml.append("<faxEmpresa>");
				xml.append((vfichaOs3.getFaxempresa() != null) ? vfichaOs3
						.getFaxempresa() : "");
				xml.append("</faxEmpresa>");
				xml.append("<claseCentroTrabajo>");
				xml.append((vfichaOs3.getClasecentrotrabajo() != null) ? vfichaOs3
						.getClasecentrotrabajo() : "");
				xml.append("</claseCentroTrabajo>");
				xml.append("<plantillaTotalEmpresa>");
				xml.append((vfichaOs3.getPlantillatotalempresa() != null) ? vfichaOs3
						.getPlantillatotalempresa() : "");
				xml.append("</plantillaTotalEmpresa>");
				xml.append("<fechaEvaluacionRiesgos>");
				xml.append((vfichaOs3.getFechaevaluacionriesgos() != null) ? vfichaOs3
						.getFechaevaluacionriesgos() : "");
				xml.append("</fechaEvaluacionRiesgos>");
				xml.append("<riesgosExistentes>");
				xml.append((vfichaOs3.getRiesgosexistentes() != null) ? vfichaOs3
						.getRiesgosexistentes() : "");
				xml.append("</riesgosExistentes>");
				xml.append("<actividadPreventiva>");
				xml.append((vfichaOs3.getActividadpreventiva() != null) ? vfichaOs3
						.getActividadpreventiva() : "");
				xml.append("</actividadPreventiva>");
				xml.append("</imprimirOS3>");
			}
			xml.append("</impresiones>");

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

	/**
	 * /** Devuelve el objeto ficha apertura con los datos.
	 * 
	 *  pkFicha
	 *            String
	 *  VfichaOs3
	 *
	 * @param pkFicha the pk ficha
	 * @return the vficha os 3
	 */
	private VfichaOs3 obtenerfichaOs3(String pkFicha) {
		String numExp = "";
		VfichaOs3 fichaOs3 = new VfichaOs3();

		numExp = pkFicha.replaceAll("/", "-");
		fichaOs3.setNumexpediente(numExp);

		return this.vfichaOs3Service.find(fichaOs3);
	}
}
