package com.rjconsultores.ventaboletos.web.gui.controladores.relatorios;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.activation.MimetypesFileTypeMap;
import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Filedownload;

import com.rjconsultores.integracaoreceitadespesa.Arquivo;
import com.rjconsultores.integracaoreceitadespesa.dao.Totalbus;
import com.rjconsultores.integracaoreceitadespesa.entidades.DespesaReceita;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.web.utilerias.MyComboboxEmpresa;
import com.rjconsultores.ventaboletos.web.utilerias.MyComboboxPuntoVenta;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;

@Controller("relatorioArquivoBGMController")
@Scope("prototype")
public class RelatorioArquivoBGMController extends MyGenericForwardComposer {

	private static final long serialVersionUID = 1L;
	private static Logger log = Logger.getLogger(RelatorioArquivoBGMController.class);
	private static final int TAMANHO_BUFFER = 4096; // 4kb

	private MyComboboxEmpresa cmbEmpresa;
	private MyComboboxPuntoVenta cmbPuntoVenta;
	private Datebox datInicial;
	private Datebox datFinal;

	@Autowired
	private DataSource dataSource;

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);

	}

	public void onClick$btnExecutarRelatorio(Event ev) throws Exception {
		executarRelatorio();
	}

	/**
	 * @throws Exception
	 * 
	 */
	private void executarRelatorio() throws Exception {	     
		excluirArquivosZip();
		List<File> files = new ArrayList<File>();
		Calendar cal = Calendar.getInstance();
		// Seta primeiro dia da iteração
		cal.setTime(datInicial.getValue());
		Calendar calFinal = Calendar.getInstance();
		calFinal.setTime(datFinal.getValue());
		// seta dia e mês finais para limite da iteração
		int diaFinal = calFinal.get(Calendar.DAY_OF_MONTH);
		int mesFinal = calFinal.get(Calendar.MONTH);
		Connection con = null;
		try{
			con = dataSource.getConnection();
		
			while (cal.get(Calendar.DAY_OF_MONTH) <= diaFinal && cal.get(Calendar.MONTH) <= mesFinal) {
				String fileName = System.getProperty("jboss.server.log.dir") + "/BGM-" + cal.get(Calendar.YEAR) + "" + DespesaReceita.lpad(Integer.toString(cal.get(Calendar.MONTH) + 1), "0", 2) + "" + DespesaReceita.lpad(Integer.toString(cal.get(Calendar.DAY_OF_MONTH)), "0", 2) + ".txt";
				File file = new File(fileName);
				
				Totalbus totalbus = new Totalbus(con);
	
				log.debug("gerando arquivo...");
				Arquivo.GravaArquivo(file.getAbsolutePath(), totalbus.getDespesasReceitas(
						cmbPuntoVenta.getSelectedItem() == null ? null : ((PuntoVenta)cmbPuntoVenta.getSelectedItem().getValue()).getPuntoventaId(), 
						cmbEmpresa.getSelectedItem() == null ? null : ((Empresa)cmbEmpresa.getSelectedItem().getValue()).getEmpresaId(), 
								cal.getTime()));
				// adiciona um dia para iteração
				cal.add(Calendar.DAY_OF_MONTH, 1);
				files.add(file);
			}
			
			
			String fileZip = System.getProperty("jboss.server.log.dir") + "/ArquivosBGM.zip";
			log.debug("nome arquivo: " + fileZip);
	    	FileInputStream inputStream;
	    	
			compactarArquivos(files, fileZip);
			File filez = new File(fileZip);
			log.info(filez.exists());
	        if (filez.exists()) {
	        	log.debug("download dos arquivos");
	            inputStream = new FileInputStream(filez);
	            Filedownload.save(inputStream, new MimetypesFileTypeMap().getContentType(filez), filez.getName());
	        }
	        filez.delete(); 
	        
		} finally {
        	con.close();
        }
	}

	public static void compactarArquivo(String arqSaida,String arqEntrada) throws IOException{        
		int cont;        
		byte[] dados = new byte[TAMANHO_BUFFER];                            
		BufferedInputStream origem = null;        
		FileInputStream streamDeEntrada = null;        
		FileOutputStream destino = null;        
		ZipOutputStream saida = null;        
		ZipEntry entry = null;                       
		try {             
			destino = new FileOutputStream(new File(arqSaida));             
			saida = new ZipOutputStream(new BufferedOutputStream(destino));             
			File file = new File(arqEntrada);             
			streamDeEntrada = new FileInputStream(file);             
			origem = new BufferedInputStream(streamDeEntrada, TAMANHO_BUFFER);             
			entry = new ZipEntry(file.getName());             
			saida.putNextEntry(entry);                                     
			while((cont = origem.read(dados, 0, TAMANHO_BUFFER)) != -1) {                 
				saida.write(dados, 0, cont);             
			}             
			origem.close();             
			saida.close();        
		} catch(IOException e) {             
			log.error(e.getMessage());
			throw new IOException(e.getMessage());
		}    
	}
	
	private void compactarArquivos(List<File> arquivosEOuPastas, String arquivoDeSaida){   
		System.out.println(arquivoDeSaida);
		log.debug(arquivoDeSaida);

         // Create a buffer for reading the files  
         byte[] buf = new byte[1024];  

         try {  
             // Create the ZIP file  
             ZipOutputStream out = new ZipOutputStream(new FileOutputStream(arquivoDeSaida));  

             // Compress the files  
             for (File f : arquivosEOuPastas) {  
                 FileInputStream in = new FileInputStream(f.getPath());  

                 // Add ZIP entry to output stream.  
                 out.putNextEntry(new ZipEntry(f.getName()));  
                    System.out.println(f.getPath());  
                 // Transfer bytes from the file to the ZIP file  
                 int len;  
                 while ((len = in.read(buf)) > 0) {  
                     out.write(buf, 0, len);  
                 }  

                 // Complete the entry  
                 out.closeEntry();  
                 in.close();  
                 f.delete();
             }  

             // Complete the ZIP file  
             out.close();  
         } catch (IOException e) { 
        	 log.error(e.getMessage(),e);
             e.printStackTrace();  
         }  
     }  
	
	private void excluirArquivosZip(){
		File pasta = new File(System.getProperty("jboss.server.log.dir"));    
		File[] arquivos = pasta.listFiles();    
		    
		for(File arquivo : arquivos) {
		    if(arquivo.getName().endsWith("zip")) {
		        arquivo.delete();
		    }
		}
	}
	
	public MyComboboxEmpresa getCmbEmpresa() {
		return cmbEmpresa;
	}

	public void setCmbEmpresa(MyComboboxEmpresa cmbEmpresa) {
		this.cmbEmpresa = cmbEmpresa;
	}

	public MyComboboxPuntoVenta getCmbPuntoVenta() {
		return cmbPuntoVenta;
	}

	public void setCmbPuntoVenta(MyComboboxPuntoVenta cmbPuntoVenta) {
		this.cmbPuntoVenta = cmbPuntoVenta;
	}

	public Datebox getDatInicial() {
		return datInicial;
	}

	public void setDatInicial(Datebox datInicial) {
		this.datInicial = datInicial;
	}

	public Datebox getDatFinal() {
		return datFinal;
	}

	public void setDatFinal(Datebox datFinal) {
		this.datFinal = datFinal;
	}
	

}
