package com.fitbank.formmanager;

import com.FitBank.xml.Formas.Formulario;
import com.fitbank.common.Helper;
import com.fitbank.contentsmanager.ManagerUtils;
import com.fitbank.webpages.WebPage;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.Clob;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.prefs.Preferences;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.SQLQuery;
import org.hibernate.ScrollableResults;

/**
 * Clase que permite descargar formularios de la base de datos.
 * 
 * @author SoftwareHouse S.A.
 */
public class FormDownloader {

    private static final String SQL_FORMS = "SELECT CSUBSISTEMA, CTRANSACCION, TIPOFORMATO,"
            + "FORMATOXML FROM TFORMATOXML WHERE FHASTA=:fhasta AND CSUBSISTEMA IN(:subsystems) "
            + "AND TIPOFORMATO IN (:formatTypes)";

    private Integer numeroForms;

    private final String subsystems;

    private final String path;

    private String formatTypes;

    public FormDownloader(String path, String subsystems, String formatTypes) {
        this.path = path;
        this.subsystems = subsystems;
        this.formatTypes = formatTypes;
        numeroForms = 0;
    }

    public void process() {
        try {
            ManagerUtils.openSession();
            this.getBlobsFormatoXml();
        } catch (Exception e) {
            System.out.println("Error al descargar : " + e.toString());
        }
        System.out.println(
                "######################################################################");
        System.out.println("Se descargaron correctamente los formularios de los tipos");
        System.out.println(this.formatTypes.replaceAll("'", ""));
        System.out.println("de los subsistemas " + this.subsystems.replaceAll("'", ""));
        System.out.println("Numero total de formularios descargados " + this.numeroForms);
        System.out.println(
                "######################################################################");
    }

    private void getBlobsFormatoXml() {
        Timestamp expire = Timestamp.valueOf("2999-12-31 00:00:00");
        this.formatTypes = this.formatTypes.replace("FitWeb3", WebPage.class.getName());
        this.formatTypes = this.formatTypes.replace("FitWeb2", Formulario.class.getName());
        try {
            SQLQuery query = Helper.createSQLQuery(FormDownloader.SQL_FORMS);
            query.setTimestamp("fhasta", expire);
            query.setParameterList("subsystems", subsystems.split(","));
            query.setParameterList("formatTypes", formatTypes.split(","));
            
            ScrollableResults rs = query.scroll();

            while (rs.next()) {
                String csubsistema = (String) rs.get(0);
                String ctransaccion = (String) rs.get(1);
                String extension = ((String) rs.get(2)).equals(WebPage.class.getName()) ? ".wpx" : ".xml";
                String name = csubsistema + ctransaccion + extension;
                Clob form = (Clob) rs.get(3);
                Integer formLength = Integer.valueOf(String.valueOf(form.length()));

                System.out.print("Descargando formulario " + name + "...");
                File folder = new File(this.path + System.getProperty("file.separator") + "/" + csubsistema);
                folder.mkdirs();

                IOUtils.write(form.getSubString(1, formLength), 
                        new FileOutputStream(folder.getPath() + System.getProperty("file.separator") + name),
                        ".wpx".equals(extension) ? "UTF-8" : "ISO-8859-1");
                System.out.println("\tSe descargó correctamente");
                numeroForms++;
            }

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

    public static void main(String args[])
            throws com.FitBank.xml.Parser.ExcepcionParser {
        Preferences preferences = Preferences.userNodeForPackage(
                FormDownloader.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);
        }

        String subsystemsValues = JOptionPane.showInputDialog(null,
                new Object[]{new JLabel("Escriba los "
                    + "subsistemas a descargar, separados por comas. (Ejm. 01,06,12)")},
                "Seleccione los subsistemas",
                JOptionPane.DEFAULT_OPTION);

        List<String> lSubsystems = Arrays.asList(subsystemsValues.split(","));
        CollectionUtils.transform(lSubsystems, new Transformer() {

            @Override
            public Object transform(Object o) {
                String value = (String) o;
                if (value.contains("-")) {
                    Integer initValue = Integer.valueOf(value.split("-")[0]);
                    Integer finishValue = Integer.valueOf(value.split("-")[1]);
                    value = "";
                    boolean initial = true;

                    for (int i = initValue; i <= finishValue; i++) {
                        if (initial) {
                            value = StringUtils.leftPad(String.valueOf(i), 2, "0");
                            initial = false;
                        } else {
                            value = value.concat(",").concat(StringUtils.leftPad(String.valueOf(i), 2, "0"));
                        }
                    }
                }

                return value;
            }
        });

        subsystemsValues = StringUtils.join(lSubsystems, ",");

        List<JCheckBox> params = new LinkedList<JCheckBox>();
        params.add(new JCheckBox("FitWeb2"));
        params.add(new JCheckBox("FitWeb3"));
        JOptionPane.showConfirmDialog(null,
                params.toArray(),
                "Seleccione el tipo de formulario",
                JOptionPane.DEFAULT_OPTION);

        String formatTypes = "";
        boolean first = true;
        for (JCheckBox checkBox : params) {
            if (checkBox.isSelected()) {
                if (!first) {
                    formatTypes = formatTypes.concat(",");
                } else {
                    first = false;
                }
                formatTypes = formatTypes.concat(checkBox.getText());
            }
        }

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

        FormDownloader fd = new FormDownloader(path, subsystemsValues, formatTypes);
        fd.process();
    }

}
