package performa.form;

import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.components.ParticipantInitialisationContext;
import oneit.email.ConfigurableEmailer;
import oneit.logging.*;
import oneit.net.LoopbackHTTP;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.StorageException;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.security.SecUser;
import oneit.security.SecUserExtension;
import oneit.servlets.forms.*;
import oneit.servlets.process.*;
import oneit.utils.*;
import oneit.utils.transform.MapTransform;
import oneit.utils.transform.param.ErrorTransform;
import oneit.utils.transform.param.ORMTransform;
import oneit.utils.transform.param.PrefixCompoundTransform;
import performa.orm.AdminUser;
 

public class ForgotPasswordFP extends SaveFP
{
    private static  LoggingArea  LOG                 =   LoggingArea.createLoggingArea("ForgotPasswordFP");
    protected       int                  DEFAULT_PASSWORD_LENGTH = 6;
    protected       ConfigurableEmailer  resetCodeEmailer;

    
    @Override 
    public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException
    {
        HttpServletRequest  request     =   submission.getRequest();
        ObjectTransaction   objTran     =   process.getTransaction();
        String              email       =   (String) request.getParameter("email");
        
        Debug.assertion(email != null, "Email not avaialble");
        
        LogMgr.log(LOG, LogLevel.PROCESSING1, "Started to send pasword reset link email.", email);
        
        SecUser secUser = SecUser.searchNAME (process.getTransaction(), email);
        
        if(secUser==null)
        {
            SecUser[]   userSearch  =   SecUser.SearchByALL().andEmail(new EqualsFilter<>(email)).search(objTran);

            if(userSearch.length>0)
            {
                secUser =   userSearch[0];
            }
        }
        
        if(secUser!=null)
        {
            LogMgr.log(LOG, LogLevel.PROCESSING1, "Inside ForgotPasswordFP for send reset pasword link mail to ", email);

            AdminUser   adminUser   =   secUser.getExtensionOrCreate(AdminUser.REFERENCE_AdminUser);
            
            if(adminUser.getForgotPasswordKey()==null)
            {
                String resetCode = new RandomStringGen().generateHumanAlphaNum(new Integer(DEFAULT_PASSWORD_LENGTH));
                adminUser.setForgotPasswordKey(resetCode);
            }
            
            adminUser.setForgotPasswordMailSendDate(new Date());
            
            Map                     emailParams         =   CollectionUtils.mapEntry("resetcode", adminUser.getForgotPasswordKey())
                                                                        .mapEntry("url", LoopbackHTTP.getRemoteAccessURL() 
                                                                                                + "/extensions/adminportal/reset_password.jsp"
                                                                                                + "?id=" + adminUser.getID() 
                                                                                                + "&key=" + adminUser.getForgotPasswordKey()).toMap();

            PrefixCompoundTransform compoundTransform   = new PrefixCompoundTransform();
            ObjectTransform         defaultTransform    = new MapTransform(emailParams);  

            compoundTransform.setDefault(defaultTransform);

            compoundTransform.add("user", new ORMTransform(secUser));

            ObjectTransform transform = new StringUtils.NullToBlankPostTransform(new ErrorTransform(compoundTransform));
            


            try
            {
                resetCodeEmailer.sendMail(transform, new String[] { email });
                
                LogMgr.log(LOG, LogLevel.PROCESSING1, "Mail has been sent from " + ForgotPasswordFP.class + " to :: ", email);
            }
            catch(Exception e)
            {
                LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING1, e, "Error while sending email");

                throw new BusinessException("Mail can not be sent. Please contact administrator.");
            }
        }
        else
        {
            throw new BusinessException("Sorry, we don't recognize that email address.");
        }
            
        return super.processForm(process, submission, params);
    }
    
        
    public void init(ParticipantInitialisationContext context) throws InitialisationException
    {
        super.init(context);

        resetCodeEmailer = (ConfigurableEmailer)(context.getSingleChild("ResetCodeEmailer"));
    }
}