package com.fp.common.files;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;

import com.fp.ach.exception.AchException;
import com.fp.common.logger.APPLogger;

/**
 * Clase que se encarga de la lectura de los archivos Nacha
 * Cada Iterable contiene 88 registros cada uno de los cuales esta compuesto por 94 bytes
 * @author scastillo
 */
public class FileIterator implements Iterable<String> {

    /*
     * Tamanio de bytes de lectura
     * Se multiplica los 94 bytes que contiene cada registro por el numero
     * de lecturas que se desea efectuar en nuestro caso 88 registros
     * LLegan caracteres especiales de fin de registro \r\n  son 96 bytes por registro
     */
    private int size = 8448;  //antes 8272
    /**
     * Variable que contiene los bytes del archivo
     */
    BufferedInputStream bufferedInputStream = null;
    /**
     * Variable que contiene los bytes de los 88 registros
     */
    byte[] buffer = null;
    /*
     * Variable que indica el numero de registros leidos
     */
    int bytesRead;
    /*
     * Variable que contiene el contador de registros
     */
    int count;

    /**
     * Constructor por defecto de la clase
     * @param fileName Nombre del archivo a procesar
     * @throws Exception
     */
    public FileIterator(String fileName, int sizebuffer) throws Exception {
        size = sizebuffer;
        buffer = new byte[size];
        bytesRead = 0;
        count = 0;
        try {
            bufferedInputStream = new BufferedInputStream(new FileInputStream(fileName));
        } catch (FileNotFoundException ex) {
            throw new AchException("ACH-0001", "NO SE PUEDE LEER EL ARCHIVO {0}", fileName);
        }
    }

    /**
     * Interator de la clase NachaFileIterator
     * @return
     */
    public Iterator<String> iterator() {
        return new NFIterator();
    }

    /**
     * Metodo que se encarga de cerrar el archivo
     * @throws Exception
     */
    public void closeBuffer() {
        if (bufferedInputStream != null) {
            try {
                bufferedInputStream.close();
            } catch (IOException ex) {
                APPLogger.getLogger().error("No se pudo cerrar el buffer", ex);
            }
        }
    }

    /**
     * Clase privada que se encarga de realizar el Interator
     */
    private class NFIterator implements Iterator<String> {
        /*
         * Variable que contiene los 88 registros
         */

        private String currentLine;

        /**
         * Metodo que recorre los los 88 registros
         * @return
         */
        public boolean hasNext() {
            try {
                if ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
                    currentLine = new String(buffer, 0, bytesRead, "ISO-8859-1");
                    count++;
                } else {
                    currentLine = null;
                    closeBuffer();
                }
            } catch (IOException e) {
                currentLine = null;
                closeBuffer();
            }

            return currentLine != null;
        }

        /**
         * Metodo que devuelve los siguientes 88 registros
         * @return
         */
        public String next() {
            return currentLine;
        }

        /**
         * Metodo que se jecuta al elimnar un registro
         * NO HACE NADA
         */
        public void remove() {
        }
    }
}
