/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.ui.common.action;

import gov.va.med.esr.common.model.security.ESRUserPrincipal;
import gov.va.med.esr.common.model.security.ESRUserPrincipalImpl;

import gov.va.med.fw.security.InvalidSecurityCodeException;
import gov.va.med.fw.security.SecurityContext;
import gov.va.med.fw.security.UserCredentials;
import gov.va.med.fw.ui.security.ChangePasswordInfo;
import gov.va.med.fw.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

import javax.security.auth.login.AccountExpiredException;
import javax.security.auth.login.CredentialExpiredException;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

/**
 * Action handler for the change password use case.
 * 
 * @author Muddaiah Ranga
 * @version 3.0
 */
public class ChangePasswordAction extends AbstractLogonAction
{
	private static Map keyMethodMap;

    /**
     * Displays the Change password page.
     *
     * @param mapping Struts action mapping for this action
     * @param actionForm Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
	public ActionForward display(ActionMapping mapping, 
							   	 ActionForm actionForm,
								 HttpServletRequest request, 
								 HttpServletResponse response)
	throws Exception 
	{
		ChangePasswordInfoForm form = (ChangePasswordInfoForm)actionForm;
		SecurityContext securityContext = getSecurityContext(request);
		if(securityContext != null)
		{
			ESRUserPrincipal userPrincipal = (ESRUserPrincipal) securityContext.getUserPrincipal();
			form.setUserID(userPrincipal.getName());
			form.setAcceptAgreement(true);
            getUserAdminService().isSecurityCodeRequired((ESRUserPrincipalImpl)userPrincipal);
			if(userPrincipal.isPasswordChangeWarningDays())
			{
			    int dueDays = userPrincipal.getDaysRemainingToExpirePassword();
				ActionMessage message = new ActionMessage(MESSAGE_PASSWORD_EXPIRATION_WARNING,String.valueOf(dueDays));
				ActionMessages errors = getErrors(request);
				errors.add(ActionMessages.GLOBAL_MESSAGE,message);
				addErrors(request, errors);
			}
		}
		return mapping.findForward(CHANGE_PASSWORD);
	}
	
    /**
     * Changes the password.
     *
     * @param mapping Struts action mapping for this action
     * @param actionForm Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
	public ActionForward changePassword(ActionMapping mapping, 
			   							ActionForm actionForm,
										HttpServletRequest request, 
										HttpServletResponse response)
	throws Exception 
	{
		ChangePasswordInfoForm form = (ChangePasswordInfoForm)actionForm;
		ChangePasswordInfo changePasswordInfo = (ChangePasswordInfo)form.getVO();

        //Validate security code
        try {
            getUserAdminService().verifySecurityCode(
                    changePasswordInfo.getUserID(),changePasswordInfo.getSecurityCode());
			try
			{
                // Log the user out first.
                processSignout(request,form.getUserCredentials().getUserID().toUpperCase());

				getUserAdminService().changePassword(changePasswordInfo);
				form.setPassword(form.getNewPassword());
				establishSecurityContext(mapping,request,form.getUserCredentials());
				putSandboxEntry(request,PASSWORD_CHANGED_KEY,new Boolean(true));
				return mapping.findForward(HOME_PAGE);
			}
			catch(CredentialExpiredException expEx)
			{
				UserCredentials userCredentials = form.getUserCredentials();
				userCredentials.setPassword(changePasswordInfo.getNewPassword());
				establishSecurityContext(mapping,request,userCredentials);
				return mapping.findForward(HOME_PAGE);
			}
        }catch(InvalidSecurityCodeException e) {
            form.reset(mapping,request);
            form.setSecurityCodeRequired(true);

            if (StringUtils.isEmpty(changePasswordInfo.getSecurityCode())){
                //required error message
                addActionMessageForField(request,MSG_SECURITY_CODE_REQUIRED,FLD_SECURITY_CODE);
            }
            else {
                //invalid error message
                addActionMessageForField(request,MSG_SECURITY_CODE_INVALID,FLD_SECURITY_CODE);
            }
            return mapping.getInputForward();
        }        
		catch(AccountExpiredException accountEx)
		{
            form.reset(mapping,request);
            addActionMessage(request,MESSAGE_CANNOT_CHANGE_PASSWORD_ACCOUNT_EXPIRED);
		}
		catch(LoginException ex)
		{
			//Clear the passwords
            form.reset(mapping,request);
            addActionMessage(request,getActionMessage(ex));
		}
		return mapping.findForward(CHANGE_PASSWORD);
	}
	
    /**
     * Handler user action when he clicks on cancel button.
     *
     * @param mapping Struts action mapping for this action
     * @param actionForm Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
	public ActionForward cancel(ActionMapping mapping, 
								ActionForm actionForm,
								HttpServletRequest request, 
								HttpServletResponse response)
	throws Exception 
	{
		SecurityContext securityContext = getSecurityContext(request);
		if(securityContext != null)
		{
			return mapping.findForward(HOME_PAGE);
		}
		return mapping.findForward(LOGON);
	}
	
	protected Map getKeyMethodMap() 
	{
		if(keyMethodMap == null)
		{
			keyMethodMap = new HashMap();
			keyMethodMap.put("button.display","display");
			keyMethodMap.put("button.logon","changePassword");
			keyMethodMap.put("button.cancel", "cancel");
		}
        return keyMethodMap;
    }
}
