package com.ejie.ad74a.ws.client.dokusi.service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;

import com.ejie.ad74a.constantes.Constantes;
import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.util.comun.UtilTokenXlnets;
import com.ejie.ad74a.util.comun.UtilidadesFecha;
import com.ejie.ad74a.util.comun.UtilidadesXML;
import com.ejie.ad74a.util.pif.Ad74aPIFws;
import com.ejie.ad74a.ws.client.dokusi.document.T65BIFSDWSClasePort;
import com.ejie.ad74a.ws.client.dokusi.model.documentT65B.T65BAttributeListType;
import com.ejie.ad74a.ws.client.dokusi.model.documentT65B.T65BDocumentIDType;
import com.ejie.ad74a.ws.client.dokusi.model.documentT65B.T65BDocumentType;
import com.ejie.ad74a.ws.client.dokusi.model.documentT65B.T65BFormatType;
import com.ejie.ad74a.ws.client.dokusi.model.documentT65B.T65BSignatureInfoType;
import com.ejie.ad74a.ws.client.dokusi.model.documentT65B.T65BSignatureListType;
import com.ejie.ad74a.ws.client.dokusi.model.documentT65B.T65BSignatureType;
import com.ejie.ad74a.ws.client.firmaX43fn.EjgvDocument;
import com.ejie.ad74a.ws.client.firmaX43fn.InputDocument;
import com.ejie.ad74a.ws.client.firmaX43fn.InputOptions;
import com.ejie.ad74a.ws.client.firmaX43fn.PlacementType;
import com.ejie.ad74a.ws.client.firmaX43fn.ProfileType;
import com.ejie.ad74a.ws.client.firmaX43fn.X43FNSHF;

@Service(value = "FirmaService")
public class FirmaServiceImpl implements FirmaService {

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

	@Autowired
	private Properties appConfiguration;

	@Autowired
	private ReloadableResourceBundleMessageSource appMessageSource;

	@Autowired
	private DokusiService dokusiService;

	@Autowired()
	private X43FNSHF x43FNSHF;

	@Autowired
	private T65BIFSDWSClasePort t65BFSDWSClasePort;

	/**
	 * Clase que adaptara los servicios de Dokusi a nuestro sistema
	 */
	private FirmaServiceImpl() {
		super();
	}

	@Override
	public EjgvDocument crearFirma(T65BDocumentType document) {
		InputOptions inputOptions = new InputOptions();
		inputOptions.setCertificateId(this.appConfiguration.getProperty("CERTINSTANCE"));
		inputOptions.setPlacement(PlacementType.ENVELOPED);
		inputOptions.setProfile(ProfileType.PDF);
		InputDocument inputDocument = new InputDocument();
		inputDocument.setDocumentLocation(document.getContent().getPifId());
		EjgvDocument firma = null;
		try {

			String filepathPifFirma = this.x43FNSHF.createSignatureLocation(inputOptions,
					document.getContent().getPifId(), Constantes.COD_APLICACION.toLowerCase());

			InputStream is = null;
			FirmaServiceImpl.logger.info(
					"FirmaServiceImpl.crearFirma - Ad74aPIFws.getInstance().downloadDocument path = {}",
					filepathPifFirma);
			is = Ad74aPIFws.getInstance().downloadDocument(filepathPifFirma);
			String firmaStr = IOUtils.toString(is, "UTF-8");

			firma = (EjgvDocument) UtilidadesXML.stringToejgvDocument(firmaStr);

		} catch (Exception e) {
			ManagerErrors.manageException(e, "crearFirma - Error al descargar un documento de Pif");
		}
		return firma;
	}

	@Override
	public String anyadirFirma(EjgvDocument firma, T65BDocumentIDType idDocumentType, String auditUser)
			throws Exception {

		String token = UtilTokenXlnets.getTokenStringXLNets(Constantes.COD_APLICACION);
		String documentID = DokusiXMLBeanParserConverter.getT65BDocumentIDTypeAsString(idDocumentType);

		T65BFormatType t65bFormatType = new T65BFormatType();
		t65bFormatType.setExtension("pdf");
		t65bFormatType.setMimeType("application/pdf");
		t65bFormatType.setName("pdfa");
		t65bFormatType.setDescription("Description");

		T65BSignatureInfoType t65bSignatureInfoType = DokusiXMLBeanParserConverter.construirT65BSignatureInfoType(
				com.ejie.ad74a.util.constantes.Constantes.FirmaDatos.FIRMA_DEPARTMENT,
				com.ejie.ad74a.util.constantes.Constantes.FirmaDatos.FIRMA_ENTITY,
				com.ejie.ad74a.util.constantes.Constantes.FirmaDatos.FIRMA_RESPONSABILITY,
				com.ejie.ad74a.util.constantes.Constantes.FirmaDatos.FIRMA_SIGNER_ID,
				com.ejie.ad74a.util.constantes.Constantes.FirmaDatos.FIRMA_SIGNER_NAME);

		T65BSignatureType t65bSignatureType = DokusiXMLBeanParserConverter.construirT65BSignatureType(
				t65bSignatureInfoType, UtilidadesFecha.getFechaSistema(Constantes.TIMESTAMP_MASK_DEFAULT),
				firma.getHeader().getType(), firma.getHeader().getIsConservable(),
				firma.getHeader().getDocumentIsRequired(), firma.getHeader().getPlacement(),
				firma.getHeader().getFormat(), firma.getHeader().getFormat(), firma.getHeader().getTsaSerialNumber(),
				t65bFormatType);

		T65BSignatureListType t65bSignatureListType = new T65BSignatureListType();
		t65bSignatureListType.getSignature().add(t65bSignatureType);

		String firmaDokusiStr = DokusiXMLBeanParserConverter.getT65BSignatureListTypeAsString(t65bSignatureListType);

		String signature = firma.getBody().getSign();
		byte[] bytes = null;
		if (null != signature) {
			bytes = UtilidadesXML.decode(signature);
		}
		InputStream myInputStream = new ByteArrayInputStream(bytes);

		String rutaPifDokusi = this.appConfiguration.getProperty("ruta.pif.dokusi");

		String pathTo = rutaPifDokusi.concat("documentoFirmado.pdf");
		String rutaPif = Ad74aPIFws.getInstance().uploadDocument(myInputStream, pathTo, false);

		FirmaServiceImpl.logger
				.info("[FirmaServiceImpl] - anyadirFirma Antes de llamar a addSignaturesToDocument documentID: "
						+ documentID);
		FirmaServiceImpl.logger.info("Firma: " + firmaDokusiStr);

		String resultadoFirma = this.t65BFSDWSClasePort.addPadesSignaturesToDocument(token, auditUser, documentID,
				firmaDokusiStr, rutaPif);

		FirmaServiceImpl.logger
				.info("[FirmaServiceImpl] - anyadirFirma Resultado de addSignaturesToDocument: " + resultadoFirma);

		// hay que modificar los metadatos con la firma
		FirmaServiceImpl.logger
				.info("[FirmaServiceImpl] - anyadirFirma Modificamos metadatos con la firma: " + resultadoFirma);

		// T65BAttributeListType listaMetadatos = DokusiXMLBeanParserConverter
		// .generarMetadatosFirma(this.appConfiguration.getProperty("CERTINSTANCE"),
		// "EJIE");

		T65BAttributeListType listaMetadatos = DokusiXMLBeanParserConverter.generarMetadatosFirma(
				com.ejie.ad74a.util.constantes.Constantes.FirmaDatos.FIRMA_SIGNER_ID,
				com.ejie.ad74a.util.constantes.Constantes.FirmaDatos.FIRMA_SIGNER_NAME);

		String resModify = this.t65BFSDWSClasePort.modifyDocument(token, auditUser, documentID, "SAME", Boolean.TRUE,
				DokusiXMLBeanParserConverter.getT65BAttributeListTypeAsString(listaMetadatos), null);
		FirmaServiceImpl.logger
				.info("[FirmaServiceImpl] - anyadirFirma Modificamos metadatos con la firma Resultado: " + resModify);
		return resultadoFirma;

	}

}