package com.fitbank.bpmserver;

import com.fitbank.common.RequestData;
import com.fitbank.common.logger.FitbankLogger;
import com.fitbank.dto.management.Detail;
import com.fitbank.processor.AbstractCommand;
import org.apache.log4j.Logger;

/**
 * 
 * @author mateo
 */
public class BpmTransaction {

    private static final Logger LOGGER = FitbankLogger.getLogger();

    public Detail executeNormal(Detail pDetail) throws Exception {
        this.printMessage(pDetail, true);

        String instName = pDetail.findFieldByNameCreate("BPMInstanceName")
                .getStringValue();
        String classNameBpm = pDetail.findFieldByNameCreate("_BPM_CLASSNAME")
                .getStringValue();
        String className;
        if (classNameBpm != null && instName != null) {
            className = classNameBpm;
        } else if (instName != null) {
            className = "com.fitbank.bpm.maintenance.BpmSendMessageSaveData";
        } else {
            className = "com.fitbank.bpm.command.BPMInitFlow";
        }

        Object instanceCommand;
        try {
            instanceCommand = Class.forName(className).newInstance();
            AbstractCommand proc = (AbstractCommand) instanceCommand;
            Detail detail = proc.executeCommand(pDetail);
            pDetail = this.manageDetailResponse(detail, className);
        } catch (InstantiationException ex) {
            LOGGER.error(ex);
        } catch (IllegalAccessException ex) {
            LOGGER.error(ex);
        } catch (ClassNotFoundException ex) {
            LOGGER.error(ex);
        } catch (ClassCastException ex) {
            LOGGER.error(ex);
        }

        this.printMessage(pDetail, false);
        return pDetail;
    }

    private Detail manageDetailResponse(Detail detail, String className) {
        Detail rqdetail = RequestData.getOrigin() != null ? RequestData
                .getOrigin() : RequestData.getDetail();
        if (rqdetail != null) {
            rqdetail.findFieldByNameCreate("__BPM_PID__").setValue(
                    detail.findFieldByNameCreate("__BPM_PID__")
                            .getStringValue());
            rqdetail.findFieldByNameCreate("__BPM_MSGID__").setValue(
                    detail.getMessageId());
            rqdetail.findFieldByNameCreate("__BPM_USUARIO__").setValue(
                    detail.findFieldByNameCreate("USUARIO").getValue());
            rqdetail.findFieldByNameCreate("__BPM_SECUENCIA__").setValue(
                    detail.findFieldByNameCreate("SECUENCIA").getValue());
            rqdetail.findFieldByNameCreate("__BPM_RESPONSE__").setValue(
                    detail.findFieldByNameCreate("RESPONSE").getValue());
            rqdetail.findFieldByNameCreate("_BPMEND").setValue(
                    detail.findFieldByNameCreate("_BPMEND").getValue());
            rqdetail.findFieldByNameCreate("_BPM_OBS").setValue(
                    detail.findFieldByNameCreate("_BPM_OBS").getValue());
            rqdetail.findFieldByNameCreate("_BPM_CLASSNAME").setValue(className);
        }

        return rqdetail;
    }

    /**
     * Metodo que imprime el mensaje (Detail) procesado, en la consola en categoria
     * DEBUG
     * 
     * @param pDetail Mensaje
     * @param in Entrada o Salida
     * @throws Exception En caso de no poder parsear el mensaje
     */
    private void printMessage(Detail pDetail, boolean in) throws Exception {
        FitbankLogger.getLogger().debug(in ? "Mensaje recibido" : "Mensaje a entregar");
        FitbankLogger.getLogger().debug(pDetail.toXml());
    }
}