package com.test;

import com.fitbank.common.FileHelper;
import com.fitbank.common.Helper;
import com.fitbank.common.conectivity.HbSession;
import com.fitbank.common.helper.XMLParser;
import com.fitbank.dto.management.Detail;
import com.fitbank.processor.AbstractCommand;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;

/**
 * Utilitario que permite ejecutar un clase en específico, con un detail
 * en específico, usando la persistencia necesaria unicamente.
 * 
 * Este utilitario puede ejecutarse directamente (por aqui mismo) o bien
 * mediante otra clase (vease las formas del metodo process).
 * 
 * En caso de no enviar la persistencia (vesa el metodo main de esta clase) se
 * carga la persistencia completa de la ruta de persistencia definida (requerido)
 * 
 * @author Soft Warehouse S.A.
 */
public class DetailProcessor {

    private static final String DETAIL_PATH = "/path/where/your/detail/is/";

    private static final List<String> L_ENTITIES = new ArrayList<String>();

    public static void main(String[] args) throws Exception {
        System.setProperty("fitbank.persistence.path", "/path/where/your/persistence/jars/are");

        DetailProcessor dp = new DetailProcessor();
        String className = "com.fitbank.somepackage.SomeClassName";

        List<String> lEntities = new ArrayList<String>();
        lEntities.add("com.fitbank.hb.persistence.somePackage.TsomepersistenceClassName");
        lEntities.add("com.fitbank.hb.persistence.somePackage.YouCanAddAsManyPersistencesAsYouNeed");

        dp.setEntities(lEntities);
        dp.process(className, dp.getLocalDetail());
    }

    public void process(AbstractCommand ac, Detail detail) {
        if (L_ENTITIES.isEmpty()) {
            Helper.setSession(HbSession.getInstance().openSession());
        } else {
            Helper.setSession(HbSession.getInstance(L_ENTITIES.toArray(new String[0])).openSession());
        }

        try {
            Helper.beginTransaction();
            detail = ac.executeCommand(detail);
            FileHelper.writeFile(DetailProcessor.DETAIL_PATH + "out.xml", detail.toXml());
            Helper.commitTransaction();
        } catch (Exception e) {
            e.printStackTrace();
            Helper.rollbackTransaction();
        } finally {
            Helper.closeSession();
        }
    }

    public void process(String className, Detail detail) {
        if (StringUtils.isBlank(className)) {
            throw new RuntimeException("Nombre de clase a ejecutar, no enviado");
        }

        try {
            AbstractCommand ac = (AbstractCommand) Class.forName(className).newInstance();
            this.process(ac, detail);
        } catch (ClassNotFoundException cnfe) {
            throw new Error("Clase no encontrada", cnfe);
        } catch (IllegalAccessException iae) {
            throw new Error("Clase no se pudo leer", iae);
        } catch (InstantiationException ie) {
            throw new Error("Imposible instanciar la clase", ie);
        }
    }

    public void process(String className) {
        this.process(className, this.getLocalDetail());
    }

    public void process(AbstractCommand ac) {
        this.process(ac, this.getLocalDetail());
    }

    private Detail getLocalDetail() {
        try {
            String data = FileHelper.readFile(DetailProcessor.DETAIL_PATH + "in.xml");
            XMLParser xml = new XMLParser(data);
            return new Detail(xml);
        } catch (Exception e) {
            throw new Error("Problemas al leer el detail de: " + DetailProcessor.DETAIL_PATH, e);
        }
    }

    public void setEntities(List<String> lentity) {
        L_ENTITIES.addAll(lentity);
    }
}
