package performa.form;

import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.business.content.Article;
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.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.Candidate;
import performa.orm.CompanyUser;
import performa.orm.Job;
import performa.utils.WebUtils;
 

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");
        Job                 job         =   (Job) process.getAttribute("Job");
        
        Debug.assertion(email != null, "Email not avaialble");
        
        email   =   StringUtils.trim(email);

        
        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);

            Map emailParams;
            
            CompanyUser companyUser =   secUser.getExtension(CompanyUser.REFERENCE_CompanyUser);
            
            if(companyUser != null)
            {
                if(companyUser.getForgotPasswordKey() == null)
                {
                    String resetCode = new RandomStringGen().generateHumanAlphaNum(new Integer(DEFAULT_PASSWORD_LENGTH));
                    companyUser.setForgotPasswordKey(resetCode);
                }

                companyUser.setForgotPasswordMailSendDate(new Date());

                emailParams =   CollectionUtils.mapEntry("resetcode", companyUser.getForgotPasswordKey())
                                                .mapEntry("url", LoopbackHTTP.getRemoteAccessURL() 
                                                                    + "/extensions/adminportal/reset_password.jsp"
                                                                    + "?id=" + companyUser.getID() 
                                                                    + "&key=" + companyUser.getForgotPasswordKey()).toMap();
            }
            else
            {
                Candidate   candidate       =   secUser.getExtension(Candidate.REFERENCE_Candidate);
                Article     applyJobArticle =   WebUtils.getArticleByShortCut(objTran, WebUtils.APPLY_JOB);
                
                if(candidate.getForgotPasswordKey() == null)
                {
                    String resetCode = new RandomStringGen().generateHumanAlphaNum(new Integer(DEFAULT_PASSWORD_LENGTH));
                    candidate.setForgotPasswordKey(resetCode);
                }

                candidate.setForgotPasswordMailSendDate(new Date());

                emailParams =   CollectionUtils.mapEntry("resetcode", candidate.getForgotPasswordKey())
                                                .mapEntry("url",  LoopbackHTTP.getRemoteAccessURL(request)
                                                                   + applyJobArticle.getLink(request, CollectionUtils.mapEntry("cms.rm", WebUtils.RESET_PASSWORD).toMap(), "/") 
                                                                    + "&id=" + candidate.getID() 
                                                                    + "&key=" + candidate.getForgotPasswordKey()
                                                                    + "&jid=" + job.getID()).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);
    }
    
        
    @Override
    public void init(ParticipantInitialisationContext context) throws InitialisationException
    {
        super.init(context);

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