/**
 * 
 */
package com.ejie.ab61.tramita.services;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;

import com.ejie.ab61.comun.Constantes;
import com.ejie.ab61.exceptions.PifException;
import com.ejie.y31.exception.Y31JanoServiceAccesDeniedException;
import com.ejie.y31.exception.Y31JanoServiceEventJmsException;
import com.ejie.y31.exception.Y31JanoServiceFileNameFormatException;
import com.ejie.y31.exception.Y31JanoServiceFileNotFoundException;
import com.ejie.y31.exception.Y31JanoServiceGenericException;
import com.ejie.y31.exception.Y31JanoServiceMongoDbGenericException;
import com.ejie.y31.exception.Y31JanoServiceOracleGenericException;
import com.ejie.y31.factory.Y31JanoServiceAbstractFactory;
import com.ejie.y31.service.Y31JanoService;
import com.ejie.y31.vo.Y31AttachmentBean;
import com.ejie.y31.vo.Y31SecurityTmpToken;

import n38a.exe.N38APISesion;

/**
 *  
 * 
 */
@Service(value = "PifServiceImpl")
public class PifServiceImpl implements PifService {

	private static final Logger logger = LoggerFactory.getLogger(PifServiceImpl.class);

	/**
	 * Clase que hara de facade para invocar los servicios de PIF
	 */
	private PifServiceImpl() {
		super();
	}

	/**
	 * 
	 * @param sSessionToken
	 *            Sesi�n de aplicaci�n que est� escribiendo en el repositorio
	 * @param file
	 *            Stream de datos para acceder al contenido a copiar en el
	 *            repositorio
	 * @param pathTo
	 *            Ruta l�gica donde alojar el fichero. Incluir� como carpeta
	 *            principal la aplicaci�n destino (/p28b/...)
	 * @param preserveName
	 *            Indica si se desea preservar el nombre del fichero en la ruta
	 *            seleccionada sobrescribiendo el fichero si existiera. Si se
	 *            decide no preservar los nombres lo que se hace es concatenarle
	 *            una serie de d�gitos que lo hace �nico en el repositorio
	 * @param Ttl
	 *            N�mero de segundos que se desea mantener el fichero en el
	 *            repositorio. Como m�ximo se podr� fijar el n�mero de segundos
	 *            de 15 d�as naturales
	 * @return Y31AttachmentBean Y31AttachmentBean
	 * @throws PifException
	 *             excepcion en el PIF
	 */
	public Y31AttachmentBean putFile(Document sSessionToken, InputStream file, String pathTo, boolean preserveName,
			Long Ttl) throws PifException {

		logger.info("putFile: inicio");
		try {
			logger.info("putFile:getInstance");
			Y31JanoService service = Y31JanoServiceAbstractFactory.getInstance();

			// invocando el metodo
			logger.info("putFile:put");
			return service.put(sSessionToken, file, pathTo, preserveName, Ttl);

		} catch (Y31JanoServiceGenericException e) {
			logger.info("putFile:Y31JanoServiceGenericException: " + e.getMessage() + e.getCause());
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNameFormatException e) {
			logger.info("putFile:Y31JanoServiceFileNameFormatException: " + e.getMessage() + e.getCause());
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceMongoDbGenericException e) {
			logger.info("putFile:Y31JanoServiceMongoDbGenericException: " + e.getMessage() + e.getCause());
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceEventJmsException e) {
			logger.info("putFile:Y31JanoServiceEventJmsException: " + e.getMessage() + e.getCause());
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceAccesDeniedException e) {
			logger.info("putFile:Y31JanoServiceAccesDeniedException: " + e.getMessage() + e.getCause());
			throw new PifException(e.getMessage(), e.getCause());
		}

	}

	/**
	 * 
	 * @param sSessionToken
	 *            Sesi�n de aplicaci�n que est� escribiendo en el repositorio
	 * @param pathFrom
	 *            Ruta l�gica de donde se va a descargar el fichero. Incluir�
	 *            como carpeta principal la aplicaci�n destino
	 * @return InputStream
	 * @throws PifException
	 */
	public BufferedInputStream getFile(Document sSessionToken, String pathFrom) throws PifException {
		// obteniendo un objeto service
		Y31JanoService service;
		try {
			service = Y31JanoServiceAbstractFactory.getInstance();

			// invocando el metodo
			return new BufferedInputStream(service.get(sSessionToken, pathFrom));
		} catch (Y31JanoServiceGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNotFoundException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNameFormatException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceMongoDbGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceOracleGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceAccesDeniedException e) {
			throw new PifException(e.getMessage(), e.getCause());
		}

	}

	/**
	 * 
	 * @param sSessionToken
	 *            Sesi�n de aplicaci�n que est� escribiendo en el repositorio
	 * @param pathFrom
	 *            Ruta l�gica desde donde se va a mover el fichero. Incluir�
	 *            como carpeta principal la aplicaci�n origen
	 * @param pathTo
	 *            Ruta l�gica donde se va a mover el fichero. Incluir� como
	 *            carpeta principal la aplicaci�n destino
	 * @param preserveName
	 *            Indica si se desea preservar el nombre del fichero en la ruta
	 *            seleccionada sobrescribiendo el fichero si existiera. Si se
	 *            decide no preservar los nombres lo que se hace es concatenarle
	 *            una serie de d�gitos que lo hace �nico en el repositorio
	 * @return Y31AttachmentBean Y31AttachmentBean
	 * @throws PifException
	 */
	public Y31AttachmentBean moveFile(Document sSessionToken, String pathFrom, String pathTo, boolean preserveName)
			throws PifException {
		try {
			// obteniendo un objeto service
			Y31JanoService service = Y31JanoServiceAbstractFactory.getInstance();

			// Preparando los par�metros
			// Document sesion = null;
			// String from = "/r09/dni.doc";
			// String to = "/r02/dni.doc";

			// invocando el metodo
			return service.move(sSessionToken, pathFrom, pathTo, preserveName);

		} catch (Y31JanoServiceGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNameFormatException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceMongoDbGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceAccesDeniedException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceEventJmsException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNotFoundException e) {
			throw new PifException(e.getMessage(), e.getCause());
		}

	}

	/**
	 * 
	 * @param sSessionToken
	 *            Sesi�n de aplicaci�n que est� escribiendo en el repositorio
	 * @param pathFrom
	 *            Ruta l�gica desde donde se va a mover el fichero. Incluir�
	 *            como carpeta principal la aplicaci�n origen
	 * @param pathTo
	 *            Ruta l�gica donde se va a mover el fichero. Incluir� como
	 *            carpeta principal la aplicaci�n destino
	 * @param boolena
	 *            preserveName preserveName
	 * @return Y31AttachmentBean Y31AttachmentBean
	 * @throws PifException
	 */
	public Y31AttachmentBean copyFile(Document sSessionToken, String pathFrom, String pathTo, boolean preserveName)
			throws PifException {
		try {
			// obteniendo un objeto service
			Y31JanoService service = Y31JanoServiceAbstractFactory.getInstance();

			// Preparando los par�metros
			// Document sesion=null;
			// String from="/r02/dni.doc";
			// String to="/r09/dni_2.doc";

			// boolean preserveName = false;

			// invocando el metodo
			return service.copy(sSessionToken, pathFrom, pathTo, preserveName);

		} catch (Y31JanoServiceGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNameFormatException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceMongoDbGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceAccesDeniedException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceEventJmsException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNotFoundException e) {
			throw new PifException(e.getMessage(), e.getCause());
		}

	}

	/**
	 * 
	 * @param sSessionToken
	 *            Sesi�n de aplicaci�n que est� escribiendo en el repositorio
	 * @param pathFrom
	 *            Ruta l�gica desde donde se va a mover el fichero. Incluir�
	 *            como carpeta principal la aplicaci�n origen
	 * @return List<Y31AttachmentBean>
	 * @throws PifException
	 */
	public List<Y31AttachmentBean> listFile(Document sSessionToken, String pathFrom) throws PifException {
		try {
			// obteniendo un objeto service
			Y31JanoService service = Y31JanoServiceAbstractFactory.getInstance();

			// Preparando los par�metros
			// Document sesion=null;
			// String from="/r09/";

			// invocando el metodo
			return (List<Y31AttachmentBean>) service.list(sSessionToken, pathFrom);
			// Y31AttachmentBean resul = null;
			// for (int i = 0; i < files.size(); i++) {
			// resul = (Y31AttachmentBean) files.get(i);
			// }
			// return files;
		} catch (Y31JanoServiceGenericException e) {
			e.printStackTrace();
		} catch (Y31JanoServiceFileNotFoundException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNameFormatException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceMongoDbGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceAccesDeniedException e) {
			throw new PifException(e.getMessage(), e.getCause());
		}
		return null;

	}

	/**
	 * 
	 * @param sSessionToken
	 *            Sesi�n de aplicaci�n que est� escribiendo en el repositorio
	 * @param pathFrom
	 *            Ruta l�gica desde donde se va a mover el fichero. Incluir�
	 *            como carpeta principal la aplicaci�n origen
	 * @throws PifException
	 */
	public void deleteFile(Document sSessionToken, String pathFrom) throws PifException {
		try {
			// obteniendo un objeto service
			Y31JanoService service = Y31JanoServiceAbstractFactory.getInstance();

			// invocando el metodo
			service.delete(sSessionToken, pathFrom);

		} catch (Y31JanoServiceGenericException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNameFormatException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceAccesDeniedException e) {
			throw new PifException(e.getMessage(), e.getCause());
		} catch (Y31JanoServiceFileNotFoundException e) {
			throw new PifException(e.getMessage(), e.getCause());
		}

	}

	@Override
	public String getCompleteUrl(String filePath, String aplicacion) throws PifException {
		PifServiceImpl.logger.info("[PifServiceImpl: pathFile: INICIO");

		PifServiceImpl.logger.info("filePath:" + filePath);
		String urlFile = "";

		try {
			Y31JanoService service = Y31JanoServiceAbstractFactory.getInstance();
			PifServiceImpl.logger.info("[PifServiceImpl: infoFile: DESPUES DEL GETINSTANCE");

			N38APISesion n38apiSesion = new N38APISesion();
			Document sesion = n38apiSesion.n38APISesionCrearApp(aplicacion);
			Y31AttachmentBean resul = service.info(sesion, filePath);
			Y31SecurityTmpToken a = service.createToken(sesion,
					Constantes.MAGIC_NUMBER_60 * Constantes.MAGIC_NUMBER_60 * Constantes.MAGIC_NUMBER_24 * 1000l, "get",
					filePath);

			urlFile = resul.getSharedDownloadUrl(a.getId());
		} catch (Exception e) {
			throw new PifException(e.getMessage(), e.getCause());
		}

		return urlFile;
	}
}
