package com.gfi.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Agrupa utilidades para ficheros
 * 
 *  
 * 
 */
public class UtilFiles {

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

	/**
	 * Constructor privado
	 */
	private UtilFiles() {
	}

	/**
	 * Dado un fichero, devuelve su extensión.
	 * 
	 * @param file
	 *            File
	 * @return String
	 */
	public static String getFileExtension(File file) {
		String name = file != null ? file.getName() : null;
		return UtilFiles.getFileExtension(name);
	}

	/**
	 * Dado un nombre de fichero completo (nombre.ext) devuelve la extensión
	 * 
	 * @param fullName
	 *            String
	 * @return String
	 */
	public static String getFileExtension(String fullName) {
		UtilFiles.logger.trace("getFileExtension {}", fullName);
		if (Utilities.isEmpty(fullName)) {
			return null;
		}
		int dotPos = fullName.lastIndexOf(".");
		return dotPos > -1 ? fullName.substring(dotPos + 1) : null;
	}

	/**
	 * Traspasa informacion de un stream de entrada a uno de salida, de forma
	 * 'no bloqueante' (usando la libreria nio).
	 * 
	 * @param input
	 *            InputStream
	 * @param output
	 *            OutputStream
	 * @return long
	 * @throws IOException
	 *             e
	 */
	public static long stream(InputStream input, OutputStream output)
			throws IOException {
		UtilFiles.logger.trace("stream");
		ReadableByteChannel inputChannel = null;
		WritableByteChannel outputChannel = null;

		try {
			inputChannel = Channels.newChannel(input);
			outputChannel = Channels.newChannel(output);
			ByteBuffer buffer = ByteBuffer
					.allocate(UtilFiles.STREAM_ALLOCATE_BUFFER_SIZE);
			long size = 0;

			while (inputChannel.read(buffer) != -1) {
				buffer.flip();
				size += outputChannel.write(buffer);
				buffer.clear();
			}
			return size;
		} finally {
			if (outputChannel != null) {
				try {
					outputChannel.close();
				} catch (IOException e) {
					UtilFiles.logger
							.error("Error al cerrar canal de salida", e);
				}
			}
			if (inputChannel != null) {
				try {
					inputChannel.close();
				} catch (IOException e) {
					UtilFiles.logger.error("Error al cerrar canal de entrada",
							e);
				}
			}
		}
	}

	private static final int STREAM_ALLOCATE_BUFFER_SIZE = 1024;
}