/*
 * Trieda slúži na prácu s heslami užívateľov. Jej úloha je vytvoriť hash hesla,
 * overiť zadané heslo s uloženým.
 *
 * Pouzity navrhovy vzor: Singleton (Jedinacik).
 */

package vut.msa.security;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.log4j.Logger;
import sun.misc.BASE64Encoder;

/**
 *
 * @author starosta
 */
public class MessageHash {

    private static Logger log = Logger.getLogger(MessageHash.class);
    private static MessageHash instance = new MessageHash();;

    /**
     * Privátny konštruktor triedy
     */
    private MessageHash() { }

    /**
     * Funkcia vráti inštanciu triedy. V prípade, že inštancia neexistuje, tak
     * ju vytvorí zavolaním konštruktora.
     *
     * @return inštancia triedy
     */
    public static MessageHash getInstance() {

        synchronized (MessageHash.class) {
            if (instance == null)
                instance = new MessageHash();
            
            return instance;
        }
    }

    /**
     * Metoda vytvori hash (SHA-256) zo zadaneho retazca.
     *
     * @param plaintext retazec s textom, ktory sa ma zahashovat
     * @return hash zo zadaneho retazca
     */
    public synchronized String encrypt (String plaintext) {

        MessageDigest digest = null;
        try {
            digest = MessageDigest.getInstance("SHA-256");

            byte[] bytes = plaintext.getBytes("UTF-8");
            digest.update(bytes);
            digest.update(digest.digest());

            byte[] rawDigest = digest.digest();
            log.debug("Hash (SHA-256) uspesne vytvoreny z retazca.");
            
            return (new BASE64Encoder()).encode(rawDigest);

        } catch (NoSuchAlgorithmException ex) {
            log.error("System nepodporuje tento algoritmus (SHA-256).");
        } catch (UnsupportedEncodingException uex) {
            log.error("System nepodporuje toto kodovanie (UTF-8).");
        }
        
        return null;
    }

    /**
     * Metoda sluzi na overenie zadaneho retazca s hash kodom (SHA-256). Metoda
     * predpoklada, ze retazec bude uzivatelsky vstup (zadanie hesla) a hash bude
     * nacitany z databazy. Metoda potom porovna, ci uzivatel zadal spravne heslo.
     *
     * @param message textovy retazec
     * @param digest hash kod
     * @return pravda, ak bol hash vytvoreny zo zadaneho retazca. Nepravda, ak nebol.
     */
    public boolean validateMessage (String message, String digest) {

        if (digest.equals(this.encrypt(message)))
            return true;
        else
            return false;
    }
}
