package com.fp.dto.data;

import java.util.HashMap;
import java.util.Map;

import com.fp.dto.save.SaveRequest;

/**
 * Thread local que almacena los datos del SaveRequest de entrada.
 * 
 * @author Jorge Vaca
 * @version 2.1
 */
public class SaveData {
    /** Almacena una instancia de SaaveRequest con los datos de entrada. */
    private static final ThreadLocal<Map<String, Object>> threadsave = new ThreadLocal<Map<String, Object>>();

    /**
     * Metodo que entrega datos del SaveRequest.
     * 
     * @return SaveRequest
     */
    public static SaveRequest getSaveRequest() {
        Map<String, Object> m = threadsave.get();
        if (m == null) {
            return null;
        }
        return (SaveRequest) m.get("SAVEREQUEST");
    }

    /**
     * Metoo que almacena en el thread local datos de SaveRequest.
     * 
     * @param pSaveRequest
     */
    public static void setSaveRequest(SaveRequest pSaveRequest) {
        Map<String, Object> m = SaveData.getMap();
        m.put("SAVEREQUEST", pSaveRequest);
        threadsave.set(m);
    }

    /**
     * Metodo que entrega datos del SaveRequest.
     * 
     * @return SaveRequest
     */
    public static String getOriginalString() {
        Map<String, Object> m = threadsave.get();
        return (String) m.get("DATA");
    }

    /**
     * Metoo que almacena en el thread local datos de SaveRequest.
     * 
     * @param pSaveRequest
     */
    public static void setOriginalString(String pData) {
        Map<String, Object> m = SaveData.getMap();
        m.put("DATA", pData);
        threadsave.set(m);
    }

    /**
     * Entrega el map asociado al thread local.
     * 
     * @return Map<String, Object>
     * @throws Exception
     */
    public static Map<String, Object> getMap() {
        Map<String, Object> m = threadsave.get();
        if (m == null) {
            m = new HashMap<String, Object>();
            threadsave.set(m);
        }
        return m;
    }

    /**
     * Entrega el valor del codigo de persona asociado a una transaccion.
     * 
     * @return String
     * @throws Exception
     */
    public static String getPersoncode() throws Exception {
        String data = getValue("personcode");
        if (data == null) {
            data = getValue("PERSONCODE");
        }
        if ((data != null) && (data.length() > 10)) {
            data = null;
        }
        return data;
    }

    /**
     * Entrega el valor del numero de cuenta asociado a una transaccion.
     * 
     * @return String
     * @throws Exception
     */
    public static String getAccount() throws Exception {
        String data = getValue("ACCOUNT");
        if (data == null) {
            data = getValue("account");
        }
        if (data == null) {
            data = getValue("ACCOUNTNUMBER");
        }
        if (data == null) {
            data = getValue("accountnumber");
        }
        if ((data != null) && (data.length() > 20)) {
            data = null;
        }
        return data;
    }

    /**
     * Entrega el valor del numero de solicitud asociado a una transaccion.
     * 
     * @return String
     * @throws Exception
     */
    public static String getSolicitudenumber() throws Exception {
        String data = getValue("solicitudnumber");
        if (data == null) {
            data = getValue("SOLICITUDNUMBER");
        }
        if ((data != null) && (data.length() > 20)) {
            data = null;
        }
        return data;
    }

    /**
     * Entrga el valor de un key, como personcode, account, solicitudnumber.
     * 
     * @param parameter Key a buscar en la cadena json de entrada.
     * @return String
     * @throws Exception
     */
    private static String getValue(String parameter) throws Exception {
        // Si ya se cargo el valo se entrag, sio no existe en el map se parsea el mensaje.
        Object aux = SaveData.getMap().get(parameter.toUpperCase());
        String data = null;
        if ((aux == null) || (aux.toString().compareTo("") == 0)) {
            String json = SaveData.getOriginalString();
            int i = json.indexOf(parameter);
            if (i > 0) {
                int j = json.indexOf(",", i);
                data = json.substring(i, j);
                String value = null;
                int lon = data.indexOf(":");
                if (lon > 0) {
                    value = data.substring(data.indexOf(":") + 1, data.length());
                    value = value.replace("\"", "");
                }
                if (data.indexOf(":") > 0) {
                    data = data.substring(0, data.indexOf(":") - 1);
                } else {
                    data = null; // encera data.
                }
                if ((data != null) && (data.compareTo(parameter) == 0)) {
                    SaveData.getMap().put(parameter.toUpperCase(), value);
                    data = value;
                }
            }
        } else {
            data = aux.toString();
        }
        return data;
    }

    /**
     * Encera el thread local.
     */
    public static void unset() {
        threadsave.set(null);
        threadsave.remove();
    }
}
