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 java.util.HashMap;
import java.util.StringTokenizer;

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.constantes.ConstantesNum;
import com.ejie.ab04b.exception.AB04BException;
import com.ejie.ab04b.model.VenvioOs2Os3;
import com.ejie.ab04b.util.CaracteresRarosUtil;
import com.ejie.ab04b.util.Utilities;

/**
 * GeneracionPDFCartaAperturaImpl generated by UDA, 11-Jan-2017 12:23:08.
 * 
 * @author UDA
 */

@Service(value = "generacionPDFComunicacionOS2OS3Impl")
public class GeneracionPDFComunicacionOS2OS3Impl implements
		GeneracionPDFComunicacionOS2OS3Service {

	@Autowired
	private VenvioOs2Os3Service venvioOs2Os3Service;

	/**
	 * 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.COMUNICACION_OS2_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());
		}
	}

	/**
	 * Devuelve los datos para completar el xml.
	 * 
	 *  folderNumber
	 *            String
	 *  HashMap
	 *
	 * @param folderNumber the folder number
	 * @return the datos
	 */
	private HashMap getDatos(String folderNumber) {
		String folderNumberAux = folderNumber;
		String mascara = Utilities.getInstance().getDateMask();
		SimpleDateFormat sdf = new SimpleDateFormat(mascara);
		String fechaObtencion = sdf.format(new java.util.Date());
		String campoDia = fechaObtencion.substring(0, ConstantesNum.NUM_2);
		String campoMes = fechaObtencion.substring(ConstantesNum.NUM_3,
				ConstantesNum.NUM_5);
		String campoAnio = fechaObtencion.substring(ConstantesNum.NUM_6,
				ConstantesNum.NUM_10);
		String provincia = "";

		folderNumberAux = folderNumberAux.replaceAll("/", "-");

		StringTokenizer token = new StringTokenizer(folderNumberAux, "-");
		if (token.hasMoreTokens()) {
			provincia = (String) token.nextToken();
		}
		String provCast = "";
		String lugarCast = "";
		String provEusk = "";
		String lugarEusk = "";
		if ("01".equals(provincia) || "1".equals(provincia)) {
			provCast = "Alava";
			provEusk = "Araba";
			lugarCast = "Vitoria-Gasteiz";
			lugarEusk = "Vitoria-Gasteiz";
		} else if ("48".equals(provincia)) {
			provCast = "Bizkaia";
			provEusk = "Bizkaia";
			lugarCast = "Bilbao";
			lugarEusk = "Bilbo";
		} else if ("20".equals(provincia)) {
			provCast = "Gipuzkoa";
			provEusk = "Gipuzkoa";
			lugarCast = "San Sebastián";
			lugarEusk = "Donostia";
		}

		String mes = "";
		String mesEusk = "";
		switch (Integer.parseInt(campoMes)) {
		case 1: {
			mesEusk = "Urtarrila";
			mes = "Enero";
		}
			break;
		case ConstantesNum.NUM_2: {
			mesEusk = "Otsaila";
			mes = "Febrero";
		}
			break;
		case ConstantesNum.NUM_3: {
			mesEusk = "Martxoa";
			mes = "Marzo";
		}
			break;
		case ConstantesNum.NUM_4: {
			mesEusk = "Apirila";
			mes = "Abril";
		}
			break;
		case ConstantesNum.NUM_5: {
			mesEusk = "Maiatza";
			mes = "Mayo";
		}
			break;
		case ConstantesNum.NUM_6: {
			mesEusk = "Ekaina";
			mes = "Junio";
		}
			break;
		case ConstantesNum.NUM_7: {
			mesEusk = "Uztaila";
			mes = "Julio";
		}
			break;
		case ConstantesNum.NUM_8: {
			mesEusk = "Abuztua";
			mes = "Agosto";
		}
			break;
		case ConstantesNum.NUM_9: {
			mesEusk = "Iraila";
			mes = "Septiembre";
		}
			break;
		case ConstantesNum.NUM_10: {
			mesEusk = "Urria";
			mes = "Octubre";
		}
			break;
		case ConstantesNum.NUM_11: {
			mesEusk = "Azaroa";
			mes = "Noviembre";
		}
			break;
		case ConstantesNum.NUM_12: {
			mesEusk = "Abendua";
			mes = "Diciembre";
		}
			break;
		default: {
			break;
		}
		}

		HashMap datosMap = new HashMap();
		datosMap.put("anio", campoAnio);
		datosMap.put("dia", campoDia);
		datosMap.put("provinciaCast", provCast);
		datosMap.put("provinciaEusk", provEusk);
		datosMap.put("ciudadCast", lugarCast);
		datosMap.put("ciudadEusk", lugarEusk);
		datosMap.put("campoMesEusk", mesEusk);
		datosMap.put("campoMes", mes);

		return datosMap;
	}

	/**
	 * 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 {
			VenvioOs2Os3 venvioOs2Os3 = new VenvioOs2Os3();

			StringBuffer xml = new StringBuffer();
			xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			xml.append("<impresiones>");
			for (int i = 0; i < listadoFolderNumber.length; i++) {
				venvioOs2Os3 = obtenerVenvioOs2Os3(listadoFolderNumber[i]);
				HashMap datosMap = getDatos(listadoFolderNumber[i]);

				xml.append("<docOS3>");
				xml.append("<firma>");
				xml.append((venvioOs2Os3.getDescfirma() != null) ? venvioOs2Os3
						.getDescfirma() : "");

				xml.append("</firma>");
				xml.append("<fichero>");
				if (venvioOs2Os3.getFirma() != null) {
					xml.append(ConstantesDocumentos.RUTA_FIRMA_IMAGEN).append(
							"/");
					xml.append(venvioOs2Os3.getFirma());
				} else {
					xml.append("");
				}
				xml.append("</fichero>");
				xml.append("<anio>");
				xml.append(datosMap.get("anio"));
				xml.append("</anio>");
				xml.append("<mes>");
				xml.append(datosMap.get("campoMes"));
				xml.append("</mes>");
				xml.append("<mesEu>");
				xml.append(datosMap.get("campoMesEusk"));
				xml.append("</mesEu>");
				xml.append("<dia>");
				xml.append(datosMap.get("dia"));
				xml.append("</dia>");
				xml.append("<razonSocial>");
				xml.append((venvioOs2Os3.getRazonsocial() != null) ? venvioOs2Os3
						.getRazonsocial() : "");
				xml.append("</razonSocial>");
				xml.append("<DNI>");
				xml.append((venvioOs2Os3.getNumerodocumento() != null) ? venvioOs2Os3
						.getNumerodocumento() : "");
				xml.append("</DNI>");
				xml.append("<actividadPrincipal>");
				xml.append((venvioOs2Os3.getDescActividadeconomica() != null) ? venvioOs2Os3
						.getDescActividadeconomica() : "");
				xml.append("</actividadPrincipal>");
				xml.append("<CNAE>");
				xml.append((venvioOs2Os3.getActividadeconomica() != null) ? venvioOs2Os3
						.getActividadeconomica() : "");
				xml.append("</CNAE>");
				xml.append("<existeAnexSi>");
				xml.append((venvioOs2Os3.getIndanxSi() != null) ? venvioOs2Os3
						.getIndanxSi() : "");
				xml.append("</existeAnexSi>");
				xml.append("<existeAnexNo>");
				xml.append((venvioOs2Os3.getIndanxNo() != null) ? venvioOs2Os3
						.getIndanxNo() : "");
				xml.append("</existeAnexNo>");
				xml.append("<apartadoAnex>");
				xml.append((venvioOs2Os3.getApdoAnexo() != null) ? venvioOs2Os3
						.getApdoAnexo() : "");
				xml.append("</apartadoAnex>");
				xml.append("<domicilioSocial>");
				xml.append((venvioOs2Os3.getDireccion() != null) ? venvioOs2Os3
						.getDireccion() : "");
				xml.append("</domicilioSocial>");
				xml.append("<plantilla>");
				xml.append((venvioOs2Os3.getPlantilla() != null) ? venvioOs2Os3
						.getPlantilla() : "");
				xml.append("</plantilla>");
				xml.append("<territorio>");
				xml.append((venvioOs2Os3.getTerritorioempresa() != null) ? venvioOs2Os3
						.getTerritorioempresa() : "");
				xml.append("</territorio>");
				xml.append("<codPostal>");
				xml.append((venvioOs2Os3.getCp() != null) ? venvioOs2Os3
						.getCp() : "");
				xml.append("</codPostal>");
				xml.append("<municipio>");
				xml.append((venvioOs2Os3.getMunicipioempresa() != null) ? venvioOs2Os3
						.getMunicipioempresa() : "");
				xml.append("</municipio>");
				xml.append("<telefono>");
				xml.append((venvioOs2Os3.getTelefonoempresa() != null) ? venvioOs2Os3
						.getTelefonoempresa() : "");
				xml.append("</telefono>");
				xml.append("<domicilioCentro>");
				xml.append((venvioOs2Os3.getDireccioncentro() != null) ? venvioOs2Os3
						.getDireccioncentro() : "");
				xml.append("</domicilioCentro>");
				xml.append("<numApertura>");
				xml.append((venvioOs2Os3.getNumApertura() != null) ? venvioOs2Os3
						.getNumApertura() : "");
				xml.append("</numApertura>");

				xml.append("<provinciaCast>");
				xml.append(datosMap.get("provinciaCast"));
				xml.append("</provinciaCast>");
				xml.append("<provinciaEusk>");
				xml.append(datosMap.get("provinciaEusk"));
				xml.append("</provinciaEusk>");
				xml.append("<ciudadCast>");
				xml.append(datosMap.get("ciudadCast"));
				xml.append("</ciudadCast>");
				xml.append("<ciudadEusk>");
				xml.append(datosMap.get("ciudadEusk"));
				xml.append("</ciudadEusk>");
				xml.append("<piePagina>");
				xml.append((venvioOs2Os3.getPie1() != null) ? venvioOs2Os3
						.getPie1() : "");
				xml.append("</piePagina>");
				xml.append("<piePagina2>");
				xml.append((venvioOs2Os3.getPie2() != null) ? venvioOs2Os3
						.getPie2() : "");
				xml.append("</piePagina2>");
				xml.append("<email>");
				xml.append((venvioOs2Os3.getEmaemp060() != null) ? venvioOs2Os3
						.getEmaemp060() : "");
				xml.append("</email>");
				xml.append("<fax>");
				xml.append((venvioOs2Os3.getFaxemp060() != null) ? venvioOs2Os3
						.getFaxemp060() : "");
				xml.append("</fax>");

				xml.append("<claseCentroEu>");
				xml.append((venvioOs2Os3.getClasectrEusk() != null) ? venvioOs2Os3
						.getClasectrEusk() : "");
				xml.append("</claseCentroEu>");
				xml.append("<claseCentroEs>");
				xml.append((venvioOs2Os3.getClasectrCast() != null) ? venvioOs2Os3
						.getClasectrCast() : "");
				xml.append("</claseCentroEs>");
				if (venvioOs2Os3.getNueva() != null
						&& venvioOs2Os3.getNueva().equalsIgnoreCase("N")) {
					xml.append("<nuevaCreacion>Bai/Si</nuevaCreacion>");
					xml.append("<existeAntes></existeAntes>");
				} else if (venvioOs2Os3.getNueva() != null
						&& venvioOs2Os3.getNueva().equalsIgnoreCase("E")) {
					xml.append("<nuevaCreacion></nuevaCreacion>");
					xml.append("<existeAntes>Bai/Si</existeAntes>");
				}
				xml.append("</docOS3>");
			}
			xml.append("</impresiones>");
			return xml;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * /** Devuelve el objeto ficha apertura con los datos.
	 * 
	 *  pkFicha
	 *            String
	 *  VenvioOs2
	 *
	 * @param pkFicha the pk ficha
	 * @return the venvio os 2 os 3
	 */
	private VenvioOs2Os3 obtenerVenvioOs2Os3(String pkFicha) {
		String numExp = "";
		String anio = "";
		int numero = 0;
		String territorio = "";
		VenvioOs2Os3 venvioOs2Os3 = new VenvioOs2Os3();

		if (pkFicha.contains("~")) {
			StringTokenizer token = new StringTokenizer(pkFicha, "~");

			if (token.hasMoreTokens()) {
				territorio = (String) token.nextToken();
			}
			if (token.hasMoreTokens()) {
				anio = (String) token.nextToken();
			}
			if (token.hasMoreTokens()) {
				numero = Integer.parseInt((String) token.nextToken());
			}
			StringBuffer folderNumber = new StringBuffer();
			folderNumber.append(territorio).append("-");
			folderNumber.append(anio).append("-");
			folderNumber.append(numero);
			numExp = folderNumber.toString();
			venvioOs2Os3.setNumexp(numExp);
		} else {
			numExp = pkFicha.replace("/", "-");
			venvioOs2Os3.setNumexp(numExp);
		}
		return this.venvioOs2Os3Service.find(venvioOs2Os3);
	}
}
