package com.fitbank.reportmanager;

import com.fitbank.common.Helper;
import com.fitbank.contentsmanager.ManagerUtils;
import com.fitbank.util.Debug;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Timestamp;
import java.util.prefs.Preferences;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import org.apache.commons.io.IOUtils;
import org.hibernate.SQLQuery;
import org.hibernate.ScrollableResults;

/**
 * Clase que permite descargar reportes desde la base de datos
 * (jasper y jrxml en caso de existir).
 * 
 * @author SoftwareHouse S.A.
 */
public class ReportDownloader {
    private static final String SQL_REPORTS = "SELECT CFORMATOREPORTE, FORMATOREPORTE, FUENTEREPORTE"
            + " FROM TFORMATOREPORTEJASPER WHERE FHASTA=:fhasta AND CPERSONA_COMPANIA=:cia AND CIDIOMA=:cidioma";

    private Integer numeroReportes;

    private final Integer company;

    private final String path;

    private final String language;

    public ReportDownloader(String path, Integer company, String language) {
        this.path = path;
        this.company = company;
        this.language = language;
        numeroReportes = 0;
    }

    public void process() {
        try {
            ManagerUtils.openSession();
            this.getBlobsReporteJasper();
        } catch (Exception e) {
            System.out.println("Error al descargar : " + e.toString());
        }
        this.printSummary();
    }

    private void printSummary() {
        System.out.println(
                "######################################################################");
        System.out.println("Se descargaron correctamente los reportes de idioma " + this.language);
        System.out.println("de la compania " + this.company);
        System.out.println("Numero total de reportes descargados " + this.numeroReportes);
        System.out.println(
                "######################################################################");
    }

    private void getBlobsReporteJasper() {
        Timestamp expire = Timestamp.valueOf("2999-12-31 00:00:00");
        try {
            SQLQuery query = Helper.createSQLQuery(ReportDownloader.SQL_REPORTS);
            query.setTimestamp("fhasta", expire);
            query.setLong("cia", Long.valueOf(this.company));
            query.setString("cidioma", this.language);

            ScrollableResults rs = query.scroll();

            while (rs.next()) {
                String cFormatoReporte = (String) rs.get(0);
                byte[] reportFormatBytes = IOUtils.toByteArray(((Blob) rs.get(1)).getBinaryStream());
                
                Clob fuenteReporte = (Clob) rs.get(2);
                Integer reportFontLenth = Integer.valueOf(String.valueOf(fuenteReporte.length()));
                String sFuenteReporte = fuenteReporte.getSubString(1L, reportFontLenth);

                String extension = ".jasper";
                String name = cFormatoReporte + extension;

                System.out.print("Descargando reporte " + name + "...");
                IOUtils.write(reportFormatBytes, new FileOutputStream(this.path + name));
                System.out.println("\tSe descargó correctamente");

                if (this.checkJrxmlReport(fuenteReporte)) {
                    extension = ".jrxml";
                    name = cFormatoReporte + extension;
                    System.out.print("Descargando reporte " + name + "...");
                    IOUtils.write(sFuenteReporte, new FileOutputStream(this.path + name));
                    System.out.println("\tSe descargó correctamente");
                }

                numeroReportes++;
            }

            rs.close();
        } catch (Exception e) {
            System.out.println("Error al descargar el reporte : " + e.toString());
        }
    }

    private boolean checkJrxmlReport(Clob fuenteReporte) {
        try {
            JRXmlLoader.load(fuenteReporte.getAsciiStream());
            return true;
        } catch (Exception e) {
            Debug.debug("El reporte no tiene una fuente subida.. : " + e.getMessage());
            return false;
        }
    }
    public static void main(String args[])
            throws com.FitBank.xml.Parser.ExcepcionParser {
        Preferences preferences = Preferences.userNodeForPackage(
                ReportDownloader.class);

        JFileChooser jfc = new JFileChooser();
        jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

        String directorioAnterior = preferences.get("destino", "");
        jfc.setDialogTitle("Directorio destino");
        jfc.setSelectedFile(new File(directorioAnterior));

        if (jfc.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) {
            System.exit(0);
        }

        Integer company = (Integer) JOptionPane.showInputDialog(null, "Compania",
                "Ingrese el codigo de compania",
                JOptionPane.QUESTION_MESSAGE, null, new Integer[]{2, 3,
                    4, 5, 6, 7, 8, 9, 10}, 0);

        String language = (String) JOptionPane.showInputDialog(null,
                "Idioma",
                "Ingrese el idioma de los reportes",
                JOptionPane.QUESTION_MESSAGE, null, new String[]{
                    "ES", "EN", "IT", "FR",
                    "SW", "IN", "LT", "EB", "CH", "JP"}, 0);

        String path = jfc.getSelectedFile().getPath() + "/";

        ReportDownloader rd = new ReportDownloader(path, company, language);
        rd.process();
    }
}
