package com.FitBank.crypt;

import com.fitbank.common.crypto.Decrypt;

import java.lang.reflect.Method;
import java.util.ResourceBundle;

/**
 * Clase que se encarga de encriptar claves.
 */
public class CallCrypt {

    private String encryptMethod = "";
    private String compareMethod = "";
    private Object classInst     = null;
    private Class  claseInvoke   = null;

    /**
     * Metodo que obtiene nombre de clase y metodo.
     * 
     * @throws Exception Excepcion Generica.
     */
    public CallCrypt() throws Exception {

        ResourceBundle r = ResourceBundle.getBundle("fitcom");

        encryptMethod = r.getString("MPWENC");
        compareMethod = r.getString("MPWCOM");
        invokeClass();
    }

    /**
     * Metodo que devuelve clave encriptada en algoritmo diferido.
     * 
     * @param clearPassword String Valor de clave.
     * 
     * @return String clave encriptada.
     * 
     * @throws Exception Excepcion Generica.
     */
    public String getShadowPassword(String clearPassword) throws Exception {
        Decrypt de = new Decrypt();

        if(de.isWebencrypt()){
            return de.encrypt(clearPassword);    
        }

        Method metodo = claseInvoke.getMethod(splitMethodClass(encryptMethod)[1], new Class[] { String.class });

        return metodo.invoke(classInst, new Object[] { clearPassword } ).toString();
    }

    /**
     * Metodo que compara clave abierto con clave encriptada.
     * 
     * @param clearPassword String Valor de clave.
     * @param shadowPassword String HASH(Clave encriptada).
     * 
     * @return boolean resultado de comparacion.
     * 
     * @throws Exception Excepcion Generica.
     */
    public boolean compareShadowPassword(String clearPassword, String shadowPassword) throws Exception {
        Method metodo = claseInvoke.getMethod(splitMethodClass(compareMethod)[1],
        													   new Class[] { String.class, String.class });

        return metodo.invoke(classInst, new Object[] { clearPassword, shadowPassword }).toString().equals("true");
    }

    /**
     * Metodo que separa nombre metodo y nombre clase.
     * 
     * @param inString String nombre clase methodo.
     * 
     * @return String[] resultado separacion.
     * 
     * @throws Exception Excepcion Generica.
     */
    public String[] splitMethodClass(String inString) {
        String[] result   = new String[2];
        String   tmp[]    = null;
        int      classPos = 0;

        tmp       = inString.split("\\.");
        result[1] = tmp[tmp.length - 1];
        classPos  = inString.indexOf(result[1]);
        result[0] = inString.substring(0, classPos - 1);

        return result;
    }

    /**
     * Metodo que permita ejecutar clase.
     * 
     * @throws Exception Excepcion Generica.
     */
    public void invokeClass() throws Exception {
        String[] res = new String[2];
        res = splitMethodClass(this.compareMethod);

        claseInvoke = Class.forName(res[0]);
        classInst   = claseInvoke.newInstance();
    }

}
