package com.fitbank.homebanking;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import java.rmi.RemoteException;

import java.sql.Date;
import java.sql.Timestamp;

import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;

import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.myfaces.config.RuntimeConfig;
import org.apache.myfaces.config.impl.digester.elements.NavigationCase;
import org.apache.myfaces.config.impl.digester.elements.NavigationRule;

import com.fitbank.common.ApplicationDates;
import com.fitbank.common.Uid;
import com.fitbank.common.crypto.Decrypt;
import com.fitbank.common.exception.FitbankException;
import com.fitbank.common.helper.FormatDates;
import com.fitbank.common.properties.PropertiesHandler;
import com.fitbank.dto.GeneralResponse;
import com.fitbank.dto.management.Criterion;
import com.fitbank.dto.management.Detail;
import com.fitbank.dto.management.Field;
import com.fitbank.dto.management.Record;
import com.fitbank.dto.management.Table;
import com.fitbank.exception.ExceptionHandler;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import nl.captcha.Captcha;

public class DataManage extends HashMap<Object, Object> {

    private static final long serialVersionUID = 1L;
    public static final String TRN_DATA = "__trnData";
    public static final String KEY = "dm";
    public static final String DETAIL_KEY = "det";
    public static final String PREPARED_CTL = "__prep__";
    public static final String PAGING_TABLE_CTL = "_paging_";
    public static final String PARAM_CAPTURE = "__capture";
    public static final String PARAM_CAPTURE_NAME = "__capture_name";


    public DataManage() {
        super();
    }

    public String getHeaderData() {
        return "";
    }

    protected HttpSession getSession() {
        return (HttpSession)this.getExternalContext().getSession(true);
    }

    protected HttpServletRequest getRequest() {
        return (HttpServletRequest)this.getExternalContext().getRequest();
    }
    
    protected HttpServletResponse getResponse() {
        return (HttpServletResponse)this.getExternalContext().getResponse();
    }

    protected String getSessionString(String pKey) {
        return (String)this.getSession().getAttribute(pKey);
    }

    protected Integer getSessionInteger(String pKey) {
        return (Integer)this.getSession().getAttribute(pKey);
    }

    protected String getParameterString(String pKey) {
        return this.getParameterString(pKey, true);
    }

    protected String getParameterString(String pKey, boolean pRecheck) {
        String val = (String)this.getExternalContext().getRequestParameterMap().get(pKey);
        if (val == null && pRecheck) {
            ParamMap param = (ParamMap)this.get("param");
            if (param != null) {
                val = (String)param.get(pKey);
            }
        }
        return val;
    }

    @SuppressWarnings("unchecked")
    protected Set<String> getParameterNames() {
        return (Set<String>)this.getExternalContext().getRequestParameterMap().keySet();
    }

    protected ExternalContext getExternalContext() {
        return FacesContext.getCurrentInstance().getExternalContext();
    }

    protected void addErrorMessage(Throwable pError) {
        if (pError instanceof FitbankException) {
            FitbankException res = ((FitbankException)pError);
            this.addMessage(res.getMessage());
            return;
        }
        if (pError instanceof RemoteException) {
            pError = pError.getCause();
        }
        ExceptionHandler eh = new ExceptionHandler(pError, "es");
        this.addMessage(eh.getUserMessage());
    }

    protected void addMessage(String pData) {
        FacesMessage fm = new FacesMessage(pData);
        FacesContext.getCurrentInstance().addMessage("", fm);
    }

    @SuppressWarnings("unchecked")
    protected void createNavigationRule(String pName, String pNamepage) throws Exception {
        ExternalContext externalContext = this.getExternalContext();
        RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
        Iterator itrule = runtimeConfig.getNavigationRules().iterator();
        NavigationRule nr = null;
        while (itrule.hasNext()) {
            NavigationRule nrule = (NavigationRule)itrule.next();
            Iterator itrcase = nrule.getNavigationCases().iterator();

            while (itrcase.hasNext()) {
                NavigationCase ncase = (NavigationCase)itrcase.next();
                if (ncase.getFromOutcome().compareTo(pName) == 0) {
                    return;
                }
                if (ncase.getFromAction() == null && nr == null) {
                    nr = nrule;
                }
            }
        }

        NavigationCase nc = new NavigationCase();

        nc.setRedirect();
        nc.setFromOutcome(pName);
        nc.setToViewId(pNamepage);
        if (pNamepage.charAt(0) != '/') {
            nc.setToViewId("/" + pNamepage);
        }

        nr.addNavigationCase(nc);
        runtimeConfig.setNavigationRulesChanged(true);

    }

    public Transaction getTransactionMetaData() {
        String key = DataManage.TRN_DATA;
        String paramKey = this.getParameterString("_detail_");
        if (paramKey != null && paramKey.compareTo("") != 0) {
            key = paramKey;
        } else {
            paramKey = this.getSessionString("_detail_");

            if (paramKey != null && paramKey.compareTo("") != 0) {
                key = paramKey;
            }
        }
        return (Transaction)this.getSession().getAttribute(key);
    }

    private void capture(Detail det) throws Exception {
        String capture = this.getParameterString(PARAM_CAPTURE);
        if (capture != null && capture.compareTo("1") == 0) {
            String data = this.captureData();
            String captureName = this.getParameterString(PARAM_CAPTURE_NAME);
            this.setFrequentTransaction(det,data,captureName);
        }
    }

    public String authorize() {
        try {
            Detail det = this.getDetail();
            String authorize = (String)det.findFieldByNameCreate("_RETURN_").getValue();
            det.setMessageid(Uid.getString());
            det.setSubsystem(HBParam.getInstance().getStringValue("authorize.subsystem"));
            det.setTransaction(HBParam.getInstance().getStringValue("authorize.transaction"));
            det.setVersion(HBParam.getInstance().getStringValue("authorize.version"));
            BussinessDelegate bd = new BussinessDelegate();
            det = bd.process(det);
            det.findFieldByNameCreate("_RETURN_").setValue(authorize);
            //this.remove("det");
            //this.getSession().setAttribute("_detail_", "tipoCambio");
            this.put("fin", det);
            String page = this.getParameterString("_page");
            String name = page.replaceAll("\\.", "").replaceAll("\\/", "");
            this.createNavigationRule(name, page);
            return name;
        } catch (Exception e) {
            e.printStackTrace();
            this.addErrorMessage(e);
            return "";
        }
    }


    public String finantial() {
        try {
            Detail det = this.getDetail();

            det.setType(MessageTypes.MAN.name());
            Decrypt de = new Decrypt();
            if (!de.isWebencrypt()) {
                String pin = (String)det.findFieldByNameCreate("PIN").getValue();
                det.findFieldByNameCreate("PIN").setValue(de.encrypt(pin));
            }
            SimpleDateFormat sdf = new SimpleDateFormat(HBParam.getInstance().getStringValue("format.date"));
            det.findFieldByNameCreate("FECHA").setValue(sdf.format(new java.util.Date()));
            sdf = new SimpleDateFormat(HBParam.getInstance().getStringValue("format.time"));
            det.findFieldByNameCreate("HORA").setValue(sdf.format(new java.util.Date()));
            if(det.findFieldByName("COOKIE")!=null){
             if(!this.analizeCookie(det)){
             det.findFieldByName("COOKIE").setValue("3");
                 return this.go();
             }else{
             det.findFieldByName("COOKIE").setValue("2");
             }
            }
            this.process(det);
            return this.go();
        } catch (Exception e) {
            e.printStackTrace();
            this.addErrorMessage(e);
            return "";
        }
        
    }

    private Cookie getCookie(String cookieName)throws Exception{
    for(Cookie cookie:this.getRequest().getCookies()){
      if(cookie.getName().compareTo(cookieName)==0){
       return cookie;
      }
    }
    return null;
    }
    
    private boolean analizeCookie(Detail detail){
    try{
     Cookie cookie=this.getCookie(this.getCookieName());
     if(cookie != null){
     if(cookie.getValue().compareTo(this.getCookieValue(detail))==0){
     return true;
     }else{
     return false;
     }
     }
    }catch(Exception e){
     e.printStackTrace();
    }
    return false;
    }
    
    private String getCookieValue(Detail detail)throws Exception{
      
        String cookieValue="";
         for(Table table:detail.getTables()){
             for(Record record:table.getRecords()){
               for(Field field:record.getFields()){
                   if(field.getValue()!=null){
                  cookieValue+=field.getValue().toString();
                   }
               }
            }
         }
      return cookieValue;
    }
    
    private String getCookieName()throws Exception{
      return (String)this.get("user")+(String)this.get("password");
                   // +(String)this.get("sessionId")
                  //  +detail.getSubsystem()
                  //  +detail.getTransaction()
                  //  +detail.getVersion();
    }
    
    @SuppressWarnings("unchecked")
    public String go() {
        try {
            Enumeration<String> en = this.getRequest().getParameterNames();
            ParamMap param = new ParamMap(this);
            while (en.hasMoreElements()) {
                String key = (String)en.nextElement();
                param.put(key, this.getParameterString(key));
            }
            this.put("param", param);
            String page = this.getParameterString("_page");
            String tKey=this.getParameterString("h_tran_key");
            String comments=this.getParameterString("h_comments");
            String aAction=this.getParameterString("h_action");
            //if(tKey!=null && comments!=null && aAction!=null){
             this.getSession().setAttribute("TRN_KEY", tKey);
             this.getSession().setAttribute("COMMENTS", comments);
             this.getSession().setAttribute("AUTH_ACTION", aAction);
            //}
            String det = this.getParameterString("_det_capture");
            String detail = this.getParameterString("_detail_");
            if (detail != null && detail.compareTo("") != 0) {
                this.getSession().setAttribute("_detail_", detail);
            }
            Detail oDetail = this.getDetail(det);
            if(oDetail.findFieldByName("COOKIE")!=null){
                if(oDetail.findFieldByName("COOKIE")
                        .getValue().toString().compareTo("3")==0){
                        page="transactionUnMatched.jsf";
                }else if(oDetail.findFieldByName("COOKIE")
                        .getValue().toString().compareTo("1")==0){
            this.setCookie(oDetail);
                }
            }
            this.capture(oDetail);
            if (page == null) {
                return "";
            }
            String name = page.replaceAll("\\.", "").replaceAll("\\/", "");
            this.createNavigationRule(name, page);
            if (oDetail != null && oDetail.getResponse() != null)
                this.addMessage(oDetail.getResponse().getUserMessage());
            return name;
        } catch (Throwable e) {
            e.printStackTrace();
            this.addErrorMessage(e);
        }
        return "";
    }
    
    private void setCookie(Detail detail){
    try{
            Cookie cookie=this.getCookie(this.getCookieName());
                 if(cookie != null){   
                    cookie.setValue(this.getCookieValue(detail));
                 }else{
                    cookie=new Cookie(this.getCookieName(),this.getCookieValue(detail));
                 }
            this.getResponse().addCookie(cookie);
    }catch(Exception e){
     e.printStackTrace();
    }
    }

    public String getPrepareData() throws Exception { 
        String init = this.getParameterString("_init_");
        if (init != null && init.compareTo("1") == 0) {
            //this.removeOldData();
        }
        String prepare = (String)this.getDetail().findFieldByNameCreate("PREPARE").getValue();
        if (prepare != null && prepare.compareTo("1") == 0) {
            return "";
        }
        removeOldData();

        String key = DataManage.DETAIL_KEY;
        String trnKey = DataManage.TRN_DATA;
        String paramKey = this.getDetailKey(null);
        if (key.compareTo(paramKey) != 0) {
            key = paramKey;
            trnKey = paramKey;
        }
        Transaction trn = (Transaction)this.getSession().getAttribute(trnKey);
        Detail det = new Detail();
        this.prepareDetail(det, trn);
        this.put(key, det);
        this.getSession().setAttribute("ACCESS_ALLOWED", "0");
        return "";
    }

    public String getRequestData() {
        String init = this.getParameterString("_init_");
        String exp = this.getParameterString("_exp");
        if (exp != null) {
            return "";
        }
        if (init == null) {
            return "";
        }
        if (init != null && init.compareTo("1") == 0) {
            this.removeOldData();
        }

        try {
            if (((String)this.getDetail().findFieldByNameCreate("LAST_OPERATION").getValue()).compareTo(MessageTypes.MAN.name()) == 0) {
                this.getDetail().findFieldByNameCreate("LAST_OPERATION").setValue("");
                return "";
            }
        } catch (Exception e) {
           e.printStackTrace();
        }
        return this.query();
    }
        
    public String getRequestDataForce() {
        this.removeOldData(true);
        return this.query();
    }

    public String cleanAccessVariables(){
        this.getSession().setAttribute("ACCESS_ALLOWED", "0");
        this.getSession().setAttribute("ACCESS_MAIN", "0");
    /**Object access_main=this.getSession().getAttribute("ACCESS_MAIN");
    if(access_main != null){
     this.getSession().removeAttribute("ACCESS_MAIN");
    }
    Object access_allowed=this.getSession().getAttribute("ACCESS_ALLOWED");
    if(access_allowed != null){
    this.getSession().removeAttribute("ACCESS_ALLOWED");
    }*/
    return "";
    }
    
    
    public String getRequestDataOnly() {
        try {
            String type = this.getDetail().getType();
            GeneralResponse response = this.getDetail().getResponse();
            //NO CONSULTA MENSAJES DE TIPO MAN
            if(type != null && type.compareTo(MessageTypes.MAN.name())==0){
                return "";
            }
            //NO CONSULTA MENSAJES CON RESPUESTA OK
           // if(response!=null && response.getCode().compareTo("0")==0){
             //   return "";
            //}
            return this.query();
        } catch (Exception ex) {
            this.put("loginMessage", ex.getMessage());
            ex.printStackTrace();
            return "error";
        }


    }

    private void removeOldData() {

        this.removeOldData(false);
    }

    private void removeOldData(boolean pForce) {
        Set<Object> k = this.keySet();
        List<Object> keys = new ArrayList<Object>();
        for (Object key : k) {
            keys.add(key);
        }
        for (Object key : keys) {
            Object obj = this.get(key);
            if (obj instanceof Detail || obj instanceof Record || obj instanceof Table) {
                this.remove(key);
            }
        }
        String detailSet = (String)this.getSession().getAttribute("_detail_set_");
        if (!pForce) {
            if (detailSet == null || detailSet.compareTo("1") != 0) {
                this.getSession().setAttribute("_detail_", "");
            } else {
                this.getSession().setAttribute("_detail_set_", "");
            }
        } else {
            this.getSession().setAttribute("_detail_", "");
            this.getSession().setAttribute("_detail_set_", "");
        }
        this.put("param", new ParamMap(this));
    }

    public String next() {
        try {
            Detail det = this.getDetail();
            String pagingTables = (String)det.findFieldByNameCreate(PAGING_TABLE_CTL).getValue();
            if (pagingTables != null && pagingTables.compareTo("") == 0) {
                pagingTables = null;
            }
            for (Table table : det.getTables()) {
                if (pagingTables != null) {
                    if (pagingTables.indexOf(table.getAlias()) < 0) {
                        continue;
                    }
                }
                String has = table.getHasMorePages();
                if (has != null || has.compareTo("1") == 0) {
                    table.setPageNumber(table.getPageNumber() + 1);
                } else {
                    throw new Exception("Se encuentra en la última Página");
                }
            }
            return this.query(det);
        } catch (Exception e) {
            this.addErrorMessage(e);
            return "";
        }
    }

    public String prev() {
        try {
            Detail det = this.getDetail();
            String pagingTables = (String)det.findFieldByNameCreate(PAGING_TABLE_CTL).getValue();
            if (pagingTables != null && pagingTables.compareTo("") == 0) {
                pagingTables = null;
            }
            for (Table table : det.getTables()) {
                if (pagingTables != null) {
                    if (pagingTables.indexOf(table.getAlias()) < 0) {
                        continue;
                    }
                }
                int page = table.getPageNumber();
                if (page > 1) {
                    table.setPageNumber(table.getPageNumber() - 1);
                } else {
                    throw new Exception("Se encuentra en la primera Página");
                }
            }
            return this.query(det);
        } catch (Exception e) {
            this.addErrorMessage(e);
            return "";
        }
    }

    public String query(Detail det) {
        try {
            det.findFieldByNameCreate(PREPARED_CTL).setValue("true");
            Detail qryDet = new Detail();
            this.prepareHeaderData(qryDet);
            qryDet.setSubsystem(det.getSubsystem());
            qryDet.setTransaction(det.getTransaction());
            qryDet.setVersion(det.getVersion());
            for (Field ctl : det.getFields()) {
                qryDet.addField(ctl);
            }
            for (Table table : det.getTables()) {
                if (table.isReadonly()) {
                    qryDet.addTable(table);
                    continue;
                }
                Table tab = new Table(table.getName(), table.getAlias());
                qryDet.addTable(tab);
                tab.setRequestedRecords(table.getRequestedRecords());
                tab.setPageNumber(table.getPageNumber());
                for (Criterion cri : table.getCriteria()) {
                    tab.addCriterion(cri);
                }
                Iterator<Record> rec = table.getRecords().iterator();
                if (rec.hasNext()) {
                    Record record = rec.next();
                    List<Field> fields = record.getFields();
                    for (Field field : fields) {
                        field.setRealValue(null);
                    }
                    tab.addRecord(record);
                } else {
                    this.get("_tempRec_" + table.getAlias());
                }
            }
            qryDet.setType(MessageTypes.CON.name());
            this.process(qryDet);
            return "";
        } catch (Exception e) {
            this.addErrorMessage(e);
            return "";
        }
    }

    public String query() {
        try {
            Detail det = this.getDetail();
            det.findFieldByNameCreate(PREPARED_CTL).setValue("true");
            Detail qryDet = new Detail();
            this.prepareHeaderData(qryDet);
            qryDet.setSubsystem(det.getSubsystem());
            qryDet.setTransaction(det.getTransaction());
            qryDet.setVersion(det.getVersion());
            for (Field ctl : det.getFields()) {
                qryDet.addField(ctl);
            }
            for (Table table : det.getTables()) {
                if (table.isReadonly()) {
                    qryDet.addTable(table);
                    continue;
                }
                Table tab = new Table(table.getName(), table.getAlias());
                qryDet.addTable(tab);
                tab.setRequestedRecords(table.getRequestedRecords());
                tab.setPageNumber(table.getPageNumber());
                for (Criterion cri : table.getCriteria()) {
                    tab.addCriterion(cri);
                }
                Iterator<Record> rec = table.getRecords().iterator();
                if (rec.hasNext()) {
                    Record record = rec.next();
                    List<Field> fields = record.getFields();
                    for (Field field : fields) {
                        field.setRealValue(null);
                    }
                    tab.addRecord(record);
                } else {
                    this.get("_tempRec_" + table.getAlias());
                }
            }
           String sig=(String)this.getSession().getAttribute("SIG");
           if(sig!=null){
           qryDet.setType(MessageTypes.SIG.name());
           this.getSession().removeAttribute("SIG");
           if(qryDet.findFieldByNameCreate("CUSUARIO")!=null){
           qryDet.setUser((String)qryDet.findFieldByNameCreate("CUSUARIO").getValue());
           }
           }else{ 
           qryDet.setType(MessageTypes.CON.name());
           } 
           this.process(qryDet);
            return "";
        } catch (Exception e) {
            this.addErrorMessage(e);
            return "";
        }
    }

    public String logout() {
        try {
            Detail logoutDet = new Detail();
            this.prepareHeaderData(logoutDet);
            logoutDet.setSubsystem("01");
            logoutDet.setTransaction("9999");
            logoutDet.setVersion("01");
            logoutDet.findFieldByNameCreate(PREPARED_CTL).setValue("true");
            Table tab = new Table("TUSUARIOSESIONES", "TUSUARIOSESIONES");
            Record rec = new Record();
            tab.addRecord(rec);
            rec.findFieldByNameCreate("CUSUARIO").setValue(logoutDet.getUser());
            rec.findFieldByNameCreate("FHASTA").setValue(FormatDates.getDefaultExpiryTimestamp());
            rec.findFieldByNameCreate("SESION").setValue(logoutDet.getSessionid());
            rec.findFieldByNameCreate("VERSIONCONTROL").setValue("-1");
            logoutDet.addTable(tab);
            logoutDet.setType(MessageTypes.MAN.name());
            logoutDet = this.process(logoutDet);
            if (logoutDet.getResponse().getCode().compareTo(GeneralResponse.OK) == 0) {
                this.clear();
                this.getSession().invalidate();
            }
            return "";
        } catch (Exception e) {
            this.addErrorMessage(e);
            return "";
        }
    }

    private Detail getDetail() throws Exception {
        return getDetail(null);
    }

    public String getDetailKey(String pKey) {
        String key = pKey;
        if (key == null) {
            key = DataManage.DETAIL_KEY;
            String paramKey = this.getParameterString("_detail_");

            if (paramKey != null && paramKey.compareTo("") != 0) {
                key = paramKey;
            } else {
                paramKey = (String)this.getSession().getAttribute("_detail_");
                if (paramKey != null && paramKey.compareTo("") != 0) {
                    key = paramKey;
                }
            }

        }
        return key;
    }

    public Detail getDetail(String pKey) throws Exception {
        String key = getDetailKey(pKey);
        Detail det = (Detail)this.get(key);
        if (det == null) {
            det = new Detail();
            Transaction trn = this.getTransactionMetaData();
            if (trn != null) {
                this.prepareDetail(det, trn);
                this.put(key, det);
            }
        } else {
            det.findFieldByNameCreate(PREPARED_CTL).setValue("true");

        }
        return det;
    }

    public String save() {
        try {
            Detail det = this.getDetail();
            det.setType(MessageTypes.MAN.name());
            String capture = this.getParameterString(PARAM_CAPTURE);
            if (capture != null && capture.compareTo("1") == 0) {
                String data = this.captureData();
                String captureName = this.getParameterString(PARAM_CAPTURE_NAME);
                this.setFrequentTransaction(det,data,captureName);
            }
            this.process(det);
            return "";
        } catch (Exception e) {
            e.printStackTrace();
            this.addErrorMessage(e);
            return "";
        }
    }

    private void setFrequentTransaction(Detail det, String data, String captureName) throws Exception {
        Table tbl = det.findTableByAlias("mf");
        if (tbl == null) {
            tbl = new Table("TMOVIMIENTOSFRECUENTES", "mf");
        } else {
            tbl.clearRecords();
        }
        if (captureName == null || captureName.compareTo("") == 0) {
            return;
        }
        Record rec = new Record();
        tbl.addRecord(rec);
        String frq_subsistema = (String)det.findFieldByNameCreate("FRQ_SUBSISTEMA").getValue();
        String frq_transaccion = (String)det.findFieldByNameCreate("FRQ_TRANSACCION").getValue();
        String frq_version = (String)det.findFieldByNameCreate("FRQ_VERSION").getValue();
        if(frq_subsistema == null){
            frq_subsistema = det.getSubsystem();
        }
        if(frq_transaccion == null){
            frq_transaccion = det.getTransaction();
        }
        if(frq_version == null){
            frq_version = det.getVersion();
        }
        rec.findFieldByNameCreate("CUSUARIO").setRealValue(det.getUser());
        rec.findFieldByNameCreate("NOMBRETRANSACCION").setRealValue(captureName);
        rec.findFieldByNameCreate("CSUBSISTEMA").setRealValue(frq_subsistema);
        rec.findFieldByNameCreate("CTRANSACCION").setRealValue(frq_transaccion);
        rec.findFieldByNameCreate("VERSIONTRANSACCION").setRealValue(frq_version);
        rec.findFieldByNameCreate("FHASTA").setRealValue(ApplicationDates.getDefaultExpiryDate());
        rec.findFieldByNameCreate("FDESDE").setRealValue(new Timestamp(System.currentTimeMillis()));
        rec.findFieldByNameCreate("DATOS").setRealValue(data);
        det.addTable(tbl);        
    }

    public String saveWithoutLogin() {
        try {
            Detail pDetail = this.getDetail();
            pDetail.setType(MessageTypes.MAN.name());
            if(this.get("captcha")!=null){
            Captcha captcha = (Captcha) this.getSession().getAttribute(Captcha.NAME);
            if(!captcha.isCorrect((String)this.get("captcha"))){
              this.put("captchaMessage", "EL TEXTO INGRESADO NO COINCIDE CON EL TEXTO DE LA IMAGEN");
              return "loginFail";
            }
            }
            PropertiesHandler jsonProp = new PropertiesHandler("json");
            if (pDetail.findFieldByName("USUARIO") != null) {
                pDetail.setUser((String)pDetail.findFieldByName("USUARIO").getValue());
            } else {
                pDetail.setUser(jsonProp.getStringValue("json.user"));
            }
            Decrypt de = new Decrypt();
            if (!de.isWebencrypt()) {
                pDetail.setPassword(de.encrypt(jsonProp.getStringValue("json.password")));
            }
            pDetail.setIpaddress("0.0.0.0");
            pDetail.setSessionid(jsonProp.getStringValue("json.sessionId"));
            pDetail.setLanguage(jsonProp.getStringValue("json.language"));
            pDetail.setTerminal(jsonProp.getStringValue("json.terminal"));
            pDetail.setChannel(jsonProp.getStringValue("json.channel"));
            pDetail.setRole(jsonProp.getIntValue("json.rol"));
            pDetail.setCompany(jsonProp.getIntValue("json.company"));
            pDetail.setOriginbranch(jsonProp.getIntValue("json.originbranch"));
            pDetail.setOriginoffice(jsonProp.getIntValue("json.originoffice"));
            pDetail.setSecuritylevel(jsonProp.getIntValue("json.securitylevel"));
            pDetail.setAccountingdate(new java.sql.Date(System.currentTimeMillis()));
            pDetail.findFieldByNameCreate("_AUTOLOTE").setValue("1");
            Field pass = pDetail.findFieldByNameCreate("PWDANTERIOR");
            String sPass = (String)pass.getValue();
            if (sPass != null) {
                pass.setValue(de.encrypt(sPass));
            }
            pass = pDetail.findFieldByNameCreate("PWDNUEVO");
            sPass = (String)pass.getValue();
            if (sPass != null) {
                pass.setValue(de.encrypt(sPass));
            }
           
            Detail det = this.process(pDetail);
            GeneralResponse resp = det.getResponse();
            
            if ((pDetail.getTransaction().compareTo("0201") == 0 
                    || pDetail.getTransaction().compareTo("3200") == 0) 
                    && resp.getCode().compareTo(GeneralResponse.OK) == 0) {
                super.put("loginMessage", resp.getUserMessage());
                this.getSession().setAttribute("ACCESS_ALLOWED", "1");
                return "loginFail";
            }
            return "";
        } catch (Exception e) {
            e.printStackTrace();
            this.addErrorMessage(e);
            return "";
        }
    }

    private Detail setHeaderWithoutLogin(Detail pDetail)throws Exception{
    	   PropertiesHandler jsonProp=new PropertiesHandler("json");
            if(this.get("user")!=null){
            pDetail.setUser((String)this.get("user"));
            }else{
    	   pDetail.setUser(jsonProp.getStringValue("json.user"));
            }
           Decrypt de = new Decrypt();
           if (!de.isWebencrypt()) {
               pDetail.setPassword(de.encrypt(jsonProp.getStringValue("json.password")));
           }
           pDetail.setIpaddress("0.0.0.0");
           pDetail.setSessionid(jsonProp.getStringValue("json.sessionId"));
           pDetail.setLanguage(jsonProp.getStringValue("json.language"));
           pDetail.setTerminal(jsonProp.getStringValue("json.terminal"));
           pDetail.setChannel(jsonProp.getStringValue("json.channel"));
           pDetail.setRole(jsonProp.getIntValue("json.rol"));
           pDetail.setCompany(jsonProp.getIntValue("json.company"));
           pDetail.setOriginbranch(jsonProp.getIntValue("json.originbranch"));
           pDetail.setOriginoffice(jsonProp.getIntValue("json.originoffice"));
           pDetail.setSecuritylevel(jsonProp.getIntValue("json.securitylevel"));
           pDetail.setAccountingdate(new java.sql.Date(System.currentTimeMillis()));
           pDetail.findFieldByNameCreate("_AUTOLOTE").setValue("1");
           
           return pDetail;
    }
    
    void prepareHeaderData(Detail pDetail) throws Exception {
         if(this.get("sessionId")==null){
        	pDetail=this.setHeaderWithoutLogin(pDetail);
        	return;
        }
        pDetail.setUser((String)this.get("user"));
        Decrypt de = new Decrypt();
        if (!de.isWebencrypt()) {
            pDetail.setPassword(de.encrypt((String)this.get("password")));
        }
        pDetail.setIpaddress("0.0.0.0");
        pDetail.setSessionid((String)this.get("sessionId"));
        pDetail.setLanguage((String)this.get("language"));
        pDetail.setTerminal((String)this.get("terminal"));
        pDetail.setChannel((String)this.get("channel"));
        pDetail.setRole((Integer)this.get("profile"));
        pDetail.setCompany((Integer)this.get("company"));
        pDetail.setOriginbranch((Integer)this.get("originBranch"));
        pDetail.setOriginoffice((Integer)this.get("originOffice"));
        pDetail.setSecuritylevel((Integer)this.get("securityLevel"));
        pDetail.setAccountingdate((Date)this.get("accountingDate"));
        pDetail.setArea((String)this.get("area"));
    }

    public void prepareDetail(Detail pDetail, Transaction pTrn) throws Exception {
        pDetail.setSubsystem(pTrn.getSubsystem());
        pDetail.setTransaction(pTrn.getTransaction());
        pDetail.setVersion(pTrn.getVersion());
        this.prepareHeaderData(pDetail);
        Iterator<Table> it = pTrn.getTables().iterator();
        while (it.hasNext()) {
            Table table = it.next();
            pDetail.addTable(table);
            Iterator<Record> it1 = table.getRecords().iterator();
            if (it1.hasNext())
                this.put("_tempRec_" + table.getAlias(), it1.next());
        }
        Iterator<Field> itctl = pTrn.getControlFields().iterator();
        while (itctl.hasNext()) {
            pDetail.addField(itctl.next());
        }
    }

    private Detail process(Detail pDetail) throws Exception {
        try{
        Transaction trn = this.getTransactionMetaData();
        String val = (String)pDetail.findFieldByNameCreate(PREPARED_CTL).getValue();
        if (val == null || val.compareTo("true") != 0)
            this.prepareDetail(pDetail, trn);
        pDetail.setMessageid(Uid.getString());
        BussinessDelegate bd = new BussinessDelegate();
        String key = this.getDetailKey(null);
        pDetail = bd.process(pDetail);
        GeneralResponse resp = pDetail.getResponse();
            if(resp.getCode().compareTo(GeneralResponse.OK) != 0){
            if(pDetail.getTransaction().compareTo("3200")==0||pDetail.getTransaction().compareTo("0201")==0){
                this.getSession().setAttribute("ACCESS_ALLOWED", "1");
            }
            }
         if (resp.getCode().compareTo(GeneralResponse.OK) != 0) {
         this.put("loginMessage", resp.getUserMessage());
         }
        
        if (pDetail.getType().compareTo("CON") == 0) {
            this.cleanRecords(pDetail);
        }
        if (pDetail.getType().compareTo(MessageTypes.MAN.name()) == 0) {
            pDetail.findFieldByNameCreate("LAST_OPERATION").setValue(MessageTypes.MAN.name());
        }
        String noReport = (String)pDetail.findFieldByNameCreate("NO_REPORT").getRealValue();
        if (noReport == null || noReport.compareTo("1") != 0) {
            this.validateReport(pDetail);
        }
       if(pDetail.getTransaction().compareTo("6022")==0){  
       super.put("shootMessage", pDetail.getResponse().getUserMessage());
       }
        this.validateResponse(pDetail.getResponse());
        this.put(key, pDetail);
        return pDetail;
        }catch(Throwable e){
        e.printStackTrace();
        throw new Exception(e);
        }
    }

    private Detail cleanRecords(Detail pDetail) throws Exception {
        Iterator<Table> tables = pDetail.getTables().iterator();
        Table table = null;
        while (tables.hasNext()) {
            table = tables.next();
            table.clearEmptyRecords();
        }
        return pDetail;
    }

    private void validateReport(Detail pDetail) throws Exception {
        Iterator<Table> it = pDetail.getTables().iterator();
        while (it.hasNext()) {
            Table table = it.next();
            table.clearEmptyRecords();
        }
        this.getSession().setAttribute("repDetail", pDetail);
    }

    protected void validateResponse(GeneralResponse pResponse) throws FitbankException {
        if (pResponse.getCode().compareTo(GeneralResponse.OK) != 0) {
            super.put("shootMessage", pResponse.getUserMessage());
            throw new FitbankException(pResponse.getCode(), pResponse.getUserMessage());
        } else {
            this.addMessage(pResponse.getUserMessage());
        }
    }
    
    private void delUserMessage()throws Exception{
      super.put("shootMessage", "");
    }

    @Override
    public Object get(Object key) {
        Object sessionId = super.get("sessionId");
        if (((String)key).compareTo("requestDataOnly") == 0) {
            return this.getRequestDataOnly();
        }
        if (((String)key).compareTo("requestData") == 0) {
            return this.getRequestData();
        }
        if (((String)key).compareTo("requestDataForce") == 0) {
            return this.getRequestDataForce();
        }

        if (((String)key).compareTo("removeLoginMessage") == 0) {
            this.getRemoveLoginMessage();
            return "";
        }

        if (((String)key).compareTo("prepareData") == 0) {
            try {
                return this.getPrepareData();
            } catch (Exception e) {
                return e.getMessage();
            }
        }
        if (((String)key).compareTo("cleanVariables") == 0) {
            try {
                return this.cleanAccessVariables();
            } catch (Exception e) {
                return e.getMessage();
            }
        }
        
         if (((String)key).compareTo("maintain") == 0) {
            try {
                return this.save();
            } catch (Exception e) {
                return e.getMessage();
            }
        }
        if (((String)key).compareTo("removeData") == 0) {
            try {
                this.removeOldData(true);
                return "";
            } catch (Exception e) {
                return e.getMessage();
            }
        }
         if (((String)key).compareTo("delUserMessage") == 0) {
            try {
                this.delUserMessage();
                return "";
            } catch (Exception e) {
                return e.getMessage();
            }
        }
        if (((String)key).compareTo("logout") == 0) {
            if (sessionId == null) {
                return "";
            }
            try {
                if (this.getSession().getAttribute("sessionId") != null) {
                    return this.logout();
                } else {
                    return "";
                }
            } catch (Exception e1) {
                return "";
            }
        }
        if (((String)key).compareTo("menu") == 0) {
            if (sessionId == null) {
                return "";
            }
            MenuLoader ml = new MenuLoader("0", this);
            try {
                Detail det = ml.query();
                this.getSession().setAttribute("NOMBREPERSONA", det.findFieldByNameCreate("NOMBRELEGAL").getValue());
                this.getSession().setAttribute("TIPOIDENTIFICACION", det.findFieldByNameCreate("CTIPOIDENTIFICACION").getValue());
                this.getSession().setAttribute("IDENTIFICACION", det.findFieldByNameCreate("IDENTIFICACION").getValue());
                this.getSession().setAttribute("CTIPOPERSONA", det.findFieldByNameCreate("CTIPOPERSONA").getValue());
                this.getSession().setAttribute("EMBOSS", det.findFieldByNameCreate("EMBOSS").getValue());
                String rol = (String)det.findFieldByNameCreate("ROL").getValue();
                if(rol!=null && rol.indexOf(" ") > 0){
                    rol = rol.substring(0,rol.indexOf(" "));
                }
                this.getSession().setAttribute("ROL", rol);
                this.getSession().setAttribute("_menu", det);
            } catch (Exception e) {
                this.addErrorMessage(e);
            }
            return "";
        }
        if (((String)key).compareTo("submenu") == 0) {
            if (sessionId == null) {
                return "";
            }
            String level = this.getSessionString("_mLevel");
            MenuLoader ml = new MenuLoader(level, this);
            try {
                Detail det = ml.query();
                this.getSession().setAttribute("_submenu", det);
            } catch (Exception e) {
                e.printStackTrace();
                this.addErrorMessage(e);
            }
            return "";
        }
        Object obj = super.get(key);
        return obj;
    }

    public String login() {
        String ruc = null;
        try {
            Detail det = this.getDetail();
            det.findFieldByNameCreate(PREPARED_CTL).setValue("true");
            this.getSession().setAttribute("sign", "true");
            this.getSession().setAttribute("i18n", "es");
            det.setSubsystem("01");
            det.setTransaction("0000");
            det.setVersion("01");
            det.setCompany(2);
            det.setOriginbranch(HBParam.getInstance().getIntValue("sucursal.login"));
            ruc = (String)this.get("ruc");
            det.findFieldByNameCreate("RUC").setValue(this.get("ruc"));
            det.findFieldByNameCreate("TOKEN").setValue(this.get("token"));
            this.getSession().setAttribute("RUC", this.get("ruc"));
            det.setUser((String)this.get("user"));
            Field send = new Field("SEND_STR", "SIAF_LOGIN");
            det.addField(send);
            Field receive = new Field("RECEIVE_STR", "SIAF_LOGINHB_SAL");
            det.addField(receive);
            Decrypt de = new Decrypt();
            if (!de.isWebencrypt()) {
                det.setPassword(de.encrypt((String)this.get("password")));
            }
            det.setIpaddress("0.0.0.0");
            det.setType(MessageTypes.SIG.name());
            det.setMessageid(Uid.getString());
            det.setChannel("WEB");
            this.remove("sessionId");
            det.setSessionid("LOGINHB");
            BussinessDelegate bd = new BussinessDelegate();
            this.clear();
            det = bd.process(det);
            this.getSession().setAttribute("user", det.getUser());
            this.getSession().setAttribute("user_real", (String)det.findFieldByNameCreate("CUSUARIOREAL").getValue());
            GeneralResponse resp = det.getResponse();
            if (resp.getCode().compareTo(GeneralResponse.OK) != 0) {
                 this.put("loginMessage", resp.getUserMessage());
                this.getSession().setAttribute("TARJETA", det.findFieldByNameCreate("TARJETA").getValue());
                if (resp.getCode().compareTo("000001") == 0) {
                 //   this.getSession().setAttribute("ACCESS_ALLOWED", "1");
                 //   this.getRequest().getRequestDispatcher("/_18320001.jsp").forward(this.getRequest(),this.getResponse());
                 //   return "";
                    if (ruc != null && ruc.compareTo("") != 0) {
                         if(det.getRole().intValue()==19){
                             this.getSession().setAttribute("ACCESS_ALLOWED", "1");
                         return "changePin";
                         }
                         this.getSession().setAttribute("ACCESS_ALLOWED", "1");
                    return "changePin2";
                     }
                     this.getSession().setAttribute("ACCESS_ALLOWED", "1");
                    return "changePin";
                }
                if (resp.getCode().compareTo("NOIMG") == 0) {
                 this.getSession().setAttribute("ACCESS_ALLOWED", "1");   
                 return "loginFail";
                }
                super.put("loginMessage", resp.getUserMessage());
                if (ruc != null && ruc.compareTo("") != 0) {
                    return "loginOffice";
                }
                return "loginHome";  
                //}
        
              //  this.getRequest().getRequestDispatcher("/index.jsp").forward(this.getRequest(),this.getResponse());
                 
              //  return "";
            } else {
                super.put("area", det.getArea());
                super.put("loginMessage", "");
                super.put("user", det.getUser());
                super.put("password", det.getPassword());
                super.put("sessionId", det.getSessionid());
                super.put("language", det.getLanguage());
                this.getSession().setAttribute("i18n", det.getLanguage().toLowerCase());
                Locale locale = new Locale(det.getLanguage().toLowerCase());
                ResourceBundle res = ResourceBundle.getBundle("i18n", locale);
                ResourceFit resourceFit = new ResourceFit(res);
                this.getSession().setAttribute("lan", resourceFit);
                super.put("terminal", det.getTerminal());
                super.put("channel", "WEB");
                super.put("profile", det.getRole());
                super.put("company", det.getCompany());
                super.put("originBranch", det.getOriginbranch());
                super.put("originOffice", det.getOriginoffice());
                super.put("securityLevel", det.getSecuritylevel());
                super.put("accountingDate", det.getAccountingdate());
                SimpleDateFormat sdf = new SimpleDateFormat(HBParam.getInstance().getStringValue("format.date"));
                super.put("date", sdf.format(new java.util.Date()));
                sdf = new SimpleDateFormat(HBParam.getInstance().getStringValue("format.time"));
                super.put("time", sdf.format(new java.util.Date()));
                this.getSession().setAttribute("CPERSONA", det.findFieldByNameCreate("CPERSONA").getValue());
                this.getSession().setAttribute("TARJETA", det.findFieldByNameCreate("TARJETA").getValue());
                this.getSession().setAttribute("CUSUARIO", det.getUser());
                this.getSession().setAttribute("NOMBRELEGAL", det.findFieldByNameCreate("NOMBRE").getValue());
                this.getSession().setAttribute("TIPOIDENTIFICACION", det.findFieldByNameCreate("TIPOIDENTIFICACION").getValue());
                this.getSession().setAttribute("IDENTIFICACION", det.findFieldByNameCreate("IDENTIFICACION").getValue());
                det.setPassword(null);
                this.put("det", det);
            }
            this.getSession().setAttribute("ACCESS_MAIN", "1");
            //this.getRequest().getRequestDispatcher("/access.jsp").forward(this.getRequest(),this.getResponse());
            //return "";
            return "login";
        } catch (Exception e) {
            this.put("loginMessage", e.getMessage());
            this.addErrorMessage(e);
            if (ruc != null && ruc.compareTo("") != 0) {
                return "loginOffice";
            }
            return "loginHome";
        }
    }
    
    
    public String password() {
        try {
            Detail det = this.getDetail();
            det.setMessageid(Uid.getString());
            det.setLanguage("ES");
            det.setUser((String)this.getSession().getAttribute("TARJETA"));
            det.setSecuritylevel(10);
            det.setRole(1);
            det.setSessionid("LOGINHB");
            det.setTerminal("HOMEBANKING");
            det.setChannel("WEB");
            det.setIpaddress("0.0.0.0");
            det.setCompany(2);
            det.setAccountingdate(new Date(new java.util.Date().getTime()));
            det.setOriginbranch(HBParam.getInstance().getIntValue("sucursal.login"));
            det.setType(MessageTypes.MAN.name());
            Decrypt de = new Decrypt();
            if (!de.isWebencrypt()) {
                String pwdAnterior = (String)det.findFieldByNameCreate("PWDANTERIOR").getValue();
                String pwdNuevo = (String)det.findFieldByNameCreate("PWDNUEVO").getValue();
                String pwdConfirmar = (String)det.findFieldByNameCreate("PWDCONFIRMAR").getValue();
                det.findFieldByNameCreate("PWDANTERIOR").setValue(de.encrypt(pwdAnterior));
                det.findFieldByNameCreate("PWDNUEVO").setValue(de.encrypt(pwdNuevo));
                det.findFieldByNameCreate("PWDCONFIRMAR").setValue(de.encrypt(pwdConfirmar));
            }
            BussinessDelegate bd = new BussinessDelegate();
            det = bd.process(det);
            GeneralResponse resp = det.getResponse();
            String genera = (String)det.findFieldByNameCreate("GENERA").getValue();
            if (resp.getCode().compareTo(GeneralResponse.OK) != 0) {
                if (genera.compareTo("4TO6") == 0) {
                    super.put("loginMessage", resp.getUserMessage());
                    return this.getReturn(det);
                } else if (genera.compareTo("6TO6") == 0) {
                    throw new Exception(resp.getUserMessage());
                }
            } else {
                if (genera.compareTo("4TO6") == 0) {
                    super.put("loginMessage", "Su clave ha sido generada");
                    return this.getReturn(det);
                } else if (genera.compareTo("6TO6") == 0) {
                    this.addMessage(resp.getUserMessage());
                    return "";
                }
            }
            return "";
        } catch (Exception e) {
            this.addErrorMessage(e);
            return "";
        }
    }
    
    private String getReturn(Detail detail){
        try {
            String card = (String)detail.findFieldByNameCreate("TARJETA").getValue();
            if(card != null && card.length() > 4){
                if (card.substring(0, 4).compareTo("8888") == 0 || card.substring(0, 4).compareTo("9999") == 0) {
                    return "loginOffice";
                }else{
                    return "loginHome";
                }
            }else{
                return "loginHome";
            }
        } catch (Exception ex) {
            return "loginHome";
        }
    }

    private boolean validateParamKey(String pKey) throws Exception {
        if (pKey.indexOf(":") > -1) {
            return false;
        }
        List<String> list = HBParam.getInstance().getList("json.capture.exclude");
        for (String key : list) {
            if (key.trim().compareTo(pKey) == 0) {
                return false;
            }
        }
        return true;
    }

    private String captureData() throws Exception {
        String data = "";
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(bout);
        ps.println("{ identifier:'name', items: [");
        Set<String> keys = this.getParameterNames();
        boolean first = true;

        for (String key : keys) {
            if (!validateParamKey(key)) {
                continue;
            }
            if (first) {
                first = false;
            } else {
                ps.println(",");
            }
            String val = this.getParameterString(key);
            val = val.replaceAll("'", "\\'");
            ps.print("{");
            ps.print("name:'" + key + "',");
            ps.print("value:'" + val + "'");
            ps.print("}");
        }
        ps.println("]}");
        data = new String(bout.toByteArray());
        return data;
    }

    @Override
    public Object put(Object key, Object value) {
        return super.put(key, value);
    }

    public void getRemoveLoginMessage() {
        super.remove("loginMessage");
        super.remove("captchaMessage");
                            
    }
}
