/*
 * This file is part of DebGen Biobank Software developed by ASTRID Research.
 * All rights reserved. Reproduction, modification, use or disclosure
 * to third parties without express authority is forbidden.
 *
 * Copyright ASTRID Research Inc., Hungary, 2009-2011.
 *
 * ASTRID Research
 * Headquaters: Csapo utca 42. Debrecen H-4029 HUNGARY
 * Phone: +36-52-533-173        Fax: +36-52-533-174
 * Web: http://www.astrid.hu    E-mail: info@astrid.hu
 *
 * Project name: DebGen Biobank Software project.
 * URLS:
 * Developers: Istvan Zoltan Nagy (istvan.nagy@astrid.hu)
 */
package hu.astrid.debgen.forgottenpassword.service;

import elements.Functions;
import hu.astrid.debgen.authentication.domain.DebGenUser;
import hu.astrid.debgen.exception.UserNotExistException;
import hu.astrid.debgen.forgottenpassword.domain.ForgottenPasswordEntry;
import hu.astrid.shared.server.service.BaseOperationsAbstract;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import java.util.HashMap;
import java.util.List;

/**
 * The Service, which is handling the forgotten password operations.
 * @author inagy
 */
public class ForgottenPasswordService extends BaseOperationsAbstract {

    /**
     * Returns an instance of a ForgottenPasswordService and sets its session.
     * @param session The session os the Service to use the DB connection.
     * @return A new instance.
     */
    public static BaseOperationsAbstract getInstance(Session session) {
        ForgottenPasswordService forgottenPasswordService = new ForgottenPasswordService();
        forgottenPasswordService.session = session;
        return forgottenPasswordService;
    }

    /**
     * Inserts an entry of reminder e-mail indicator to the DB
     * @param email The email address of the user
     * @throws Exception When no such user found or DB fails
     */
    public HashMap<ForgottenPasswordEntry, DebGenUser> requestNewPassword(String email) throws Exception {
        Criteria criteria = session.createCriteria(DebGenUser.class).add(Restrictions.eq("email", email));
        List<DebGenUser> users = criteria.list();
        if (!users.isEmpty()) {
            DebGenUser user = users.get(0);
            ForgottenPasswordEntry entry = new ForgottenPasswordEntry();
            entry.create(user.getUserName());
            session.save(entry);
            HashMap<ForgottenPasswordEntry, DebGenUser> map = new HashMap<ForgottenPasswordEntry, DebGenUser>();
            map.put(entry, user);
            return map;
        } else {
            throw new UserNotExistException("A megadott e-mail címmel nem található felhasználó!");  //i18
        }
    }

    /**
     * Confirms the password reset operation
     * @param userName The name of the user.
     * @param confirmCode The confirmCode of this reset request.
     * @throws Exception When no such user or reset request found or DB fails...
     */
    public void confirmPassword(String userName, String confirmCode) throws Exception {
        Criteria criteria = session.createCriteria(ForgottenPasswordEntry.class).add(Restrictions.eq("userName", userName)).add(Restrictions.eq("confirmCode", confirmCode));
        List<ForgottenPasswordEntry> entries = criteria.list();
        if (!entries.isEmpty()) {
            ForgottenPasswordEntry entry = entries.get(0);
            Criteria userCriteria = session.createCriteria(DebGenUser.class).add(Restrictions.eq("userName", userName));
            DebGenUser user = (DebGenUser) userCriteria.uniqueResult();
            user.setHashedPassword(Functions.hashMD5(""));
            session.update(user);
            session.delete(entry);
        } else {
            throw new UserNotExistException("Nem létezik ilyen nevű felhasználó ezzel a jóváhagyási kóddal!");  //i18
        }
    }

    /**
     * Cancels the password reset operation
     * @param userName The name of the user.
     * @param cancelCode The cancelCode of this reset request.
     * @throws Exception When no such user or reset request found or DB fails...
     */
    public void cancelPassword(String userName, String cancelCode) throws Exception {
        Criteria criteria = session.createCriteria(ForgottenPasswordEntry.class).add(Restrictions.eq("userName", userName)).add(Restrictions.eq("cancelCode", cancelCode));
        List<ForgottenPasswordEntry> entries = criteria.list();
        if (!entries.isEmpty()) {
            ForgottenPasswordEntry entry = entries.get(0);
            session.delete(entry);
        } else {
            throw new UserNotExistException("Nem létezik ilyen nevű felhasználó ezzel a jóváhagyási kóddal!");
        }
    }
}
