/**
 * 
 */
package com.ejie.ab61.adaptadores;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.transform.TransformerException;

import org.apache.xpath.XPathAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import com.ejie.ab61.adaptadores.helper.DokusiHelper;
import com.ejie.ab61.adaptadores.service.T65BDokusiService;
import com.ejie.ab61.comun.Constantes;
import com.ejie.ab61.comun.utilidades.DOMUtilis;
import com.ejie.ab61.comun.utilidades.XlnetsUtils;
import com.ejie.ab61.model.dokusi.Metadato;
import com.ejie.ab61.tramita.adapter.PifAdapterService;

/**
 *  
 * 
 */

@Service(value = "DokusiAdapterServiceImpl")
public class T65BDokusiAdaptadorServiceImpl implements T65BDokusiAdaptadorService {

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

	@Autowired()
	private T65BDokusiService t65BDokusiService;
	@Autowired()
	private PifAdapterService pifAdapterService;

	/**
	 * M�todo que descarga un documento en DOKUSI
	 * 
	 * @param documentID
	 *            String
	 * 
	 * @return List<Object>
	 * @throws Exception
	 */
	public InputStream retrieveDocument(String documentID) throws Exception {

		T65BDokusiAdaptadorServiceImpl.logger.info("DokusiAdapterServiceImpl.retrieveDocument - " + documentID);
		try {
			String tokenSesion = XlnetsUtils.getInstance().getTokenAplicacion(true);
			String auditUser = Constantes.AUDIT_USER;
			String oidDocument = DokusiHelper.crearXMLdocumentID(documentID);
			// TODO: Comentado por PMD.
			String content = DokusiHelper.crearXMLContentPif("/ab61");

			String keysList = DokusiHelper.crearXMLReturnedAttributeKeysList(this.recuperaMetadatos());
			String respuesta = "";

			try {
				respuesta = this.t65BDokusiService.retrieveDocument(tokenSesion, auditUser, oidDocument, keysList,
						content);
			} catch (Exception e) {
				T65BDokusiAdaptadorServiceImpl.logger
						.info("DokusiAdapterServiceImpl.retrieveDocument - Return: " + respuesta);
			}
			T65BDokusiAdaptadorServiceImpl.logger
					.info("DokusiAdapterServiceImpl.retrieveDocument - Return: " + respuesta);
			// List<String> documentoDokusi =
			// T65BDokusiTransformer.transformDocumentoDokusiPifID(respuesta);

			Document documento = DOMUtilis.createDocUTF8(respuesta);

			NodeList nodosFirmas = T65BDokusiAdaptadorServiceImpl.fncParsearListaXpath(documento,
					"/document/content/pifId");

			String pifID = nodosFirmas.item(0).getFirstChild().getNodeValue();

			// DESCARGA EL DOCUMENTO DEL PIF
			InputStream bIS = this.pifAdapterService.getFile(pifID);

			return bIS;
		} catch (Exception e) {
			T65BDokusiAdaptadorServiceImpl.logger.error("DokusiAdapterServiceImpl.retrieveDocument", e);
			throw e;
		} finally {
			T65BDokusiAdaptadorServiceImpl.logger.info("DokusiAdapterServiceImpl.retrieveDocument - Final");
		}

	}

	@Override
	public String retrieveDocumentR02G(String documentID) throws Exception {
		T65BDokusiAdaptadorServiceImpl.logger.info("DokusiDaptadorServiceImpl.retrieveDocumentR02G - " + documentID);
		try {
			String tokenSession = XlnetsUtils.getInstance().getTokenAplicacion(true);
			String auditUser = Constantes.AUDIT_USER;
			String oidDocument = DokusiHelper.crearXMLdocumentID(documentID);
			String content = DokusiHelper.crearXMLContentPif(
					"/" + Constantes.CODIGO_APLICACION_TAREAS_TRAMITACION + "/" + Constantes.CODIGO_APLICACION);
			String keyList = DokusiHelper.crearXMLReturnedAttributeKeysList(this.recuperaMetadatos());
			String respuesta = "";

			try {
				respuesta = this.t65BDokusiService.retrieveDocument(tokenSession, auditUser, oidDocument, keyList,
						content);
			} catch (Exception e) {
				T65BDokusiAdaptadorServiceImpl.logger
						.error("DokusiAdpaptadorServiceImpl.retrieveDocumentR02G - Return: " + respuesta);
			}
			T65BDokusiAdaptadorServiceImpl.logger
					.info("DokusiAdaptadorServiceImpl.retrieveDocumentR02G - Return: " + respuesta);

			Document documento = DOMUtilis.createDocUTF8(respuesta);

			NodeList nodosFirmas = T65BDokusiAdaptadorServiceImpl.fncParsearListaXpath(documento,
					"/document/content/pifId");

			String pifPath = nodosFirmas.item(0).getFirstChild().getNodeValue();

			return pifPath;

		} catch (Exception e) {
			T65BDokusiAdaptadorServiceImpl.logger.error("DokusiAdaptadorServiceImpl.retrieveDocumentR02G", e);
			throw e;
		} finally {
			T65BDokusiAdaptadorServiceImpl.logger.info("DokusiAdaptadorServiceImpl.retrieveDocumentR02G - Final");
		}
	}

	@Override
	public String retrieveDocumentAplicacion(String oidDokusi, String aplicacion) throws Exception {
		T65BDokusiAdaptadorServiceImpl.logger
				.info("DokusiAdaptadorServiceImpl.retrieveDocumentAplicacion - " + oidDokusi + " - " + aplicacion);
		try {
			String tokenSession = XlnetsUtils.getInstance().getTokenAplicacion(true);
			String auditUser = Constantes.AUDIT_USER;
			String oidDocument = DokusiHelper.crearXMLdocumentID(oidDokusi);
			String content = DokusiHelper.crearXMLContentPif("/" + aplicacion);
			String keyList = DokusiHelper.crearXMLReturnedAttributeKeysList(this.recuperaMetadatos());
			String respuesta = "";

			try {
				respuesta = this.t65BDokusiService.retrieveDocument(tokenSession, auditUser, oidDocument, keyList,
						content);
			} catch (Exception e) {
				T65BDokusiAdaptadorServiceImpl.logger
						.error("DokusiAdaptadorServiceImpl.retrieveDocumentAplicacion - Return: " + respuesta);
			}
			T65BDokusiAdaptadorServiceImpl.logger
					.info("DokusiAdaptadorServiceImpl.retrieveDocumentAplicacion - Return: " + respuesta);

			Document documento = DOMUtilis.createDocUTF8(respuesta);

			NodeList nodosFirmas = T65BDokusiAdaptadorServiceImpl.fncParsearListaXpath(documento,
					"/document/content/pifId");

			String pathPif = nodosFirmas.item(0).getFirstChild().getNodeValue();

			return pathPif;
		} catch (Exception e) {
			T65BDokusiAdaptadorServiceImpl.logger.error("DokusiAdaptadorServiceImpl.retrieveDocumentAplicacion", e);
			throw e;
		} finally {
			T65BDokusiAdaptadorServiceImpl.logger.info("DokusiAdaptadorServiceImpl.retrieveDocumentAplicacion - Final");
		}
	}

	/**
	 * 
	 * @param inputStream
	 *            InputStream
	 * 
	 * @return Byte[]
	 */
	public static byte[] readDocumentContent(InputStream inputStream) {
		byte[] result = null;

		try {
			ByteArrayOutputStream buffer = new ByteArrayOutputStream();
			int nRead;
			byte[] data = new byte[Constantes.MAGIC_NUMBER_16384];

			while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
				buffer.write(data, 0, nRead);
			}
			buffer.flush();
			result = buffer.toByteArray();
		} catch (IOException e) {
			T65BDokusiAdaptadorServiceImpl.logger.info("readDocumentContent - Final");

		}

		return result;
	}

	/**
	 * Retorna el valor de un elemento de un xml, parseando con Xpath
	 * 
	 * @param documento
	 *            Document: Documento xml a parsear
	 * @param filtro
	 *            String: Filtro del elemento a buscar
	 * @return String: Valor del elemento
	 * @throws Exception
	 */
	public static NodeList fncParsearListaXpath(Document documento, String filtro) {
		NodeList listaNodos = null;
		try {
			listaNodos = XPathAPI.selectNodeList(documento, filtro);
		} catch (TransformerException e) {
			throw new RuntimeException(e.getMessage());
		}
		return listaNodos;
	}

	/**
	 * metodo q recupera los metadatos q pasarle al retrieveDocument
	 * 
	 * @return List<Metadato>
	 */
	public List<Metadato> recuperaMetadatos() {

		List<Metadato> metadatos = new ArrayList<Metadato>();

		Metadato metadato = new Metadato();
		metadato.setNombre("object_name");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("title");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_serie");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_origen");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("i_chronicle_id");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("r_version_label");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("subject");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("keywords");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("authors");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("r_creation_date");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("r_modify_date");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("r_object_type");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("acl_name");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("owner_name");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_entrada_salida");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_num_registro");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_fecha_registro");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_fecha_registro");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_formato_registro");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_libro_registro");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_registrado");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_procedimiento");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_expediente");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_entidad");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_departamento");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_proc_infraestructura");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_tipo_titularoaport");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_num_titularoaport");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_ap1_titularoaport");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_ap2_titularoaport");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_subsistema_archivo");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_fecha_archivo");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_cod_familia");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_idioma");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_fecha_documento");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_naturaleza");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_fecha_digitalizacion");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_estado");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_fecha_vigencia");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_anyo_ejercicio");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_es_firmacontenida");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_id_firmantes");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_nom_firmantes");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_es_infraestructura");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_es_editable");
		metadatos.add(metadato);

		metadato = new Metadato();
		metadato.setNombre("ejgv_es_apoyo");
		metadatos.add(metadato);

		return metadatos;
	}

}
