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

// Java Classes
import java.util.Map;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// Libraries Classes
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 net.mlw.vlh.ValueList;
import net.mlw.vlh.ValueListInfo;

// Framework Classes
import gov.va.med.fw.ui.struts.ValueListActionUtils;
import gov.va.med.fw.ui.valuelist.MaxRecordsExceededValueListException;
import gov.va.med.fw.util.StringUtils;

// ESR Classes
import gov.va.med.esr.ui.ApplicationConstants;
import gov.va.med.esr.ui.common.action.AddressForm;
import gov.va.med.esr.common.model.lookup.Country;

/**
 * This struts action is used to support the Undeliverable Mail Search page.
 *
 * @author Andrew Pach
 * @version 3.0
 */
public class UndeliverableMailSearchAction extends UndeliverableMailAction
{
    /**
     * Default constructor.
     */
    public UndeliverableMailSearchAction()
    {
        super();
    }

    /**
     * Displays the main page.
     *
     * @param mapping Struts action mapping for this action
     * @param form 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 form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        // Clear out any previously cached results.
        ValueListActionUtils
            .clearCachedResults(request.getSession(), UNDELIVERABLE_MAIL_SEARCH_TABLE_ID);

        // Return to the search display
        return mapping.findForward(FORWARD_DISPLAY);
    }

    /**
     * Resets the data to its original state.
     *
     * @param mapping Struts action mapping for this action
     * @param form 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 reset(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        // Ensure we have a valid search form
        UndeliverableMailSearchForm searchForm = getUndeliverableMailSearchForm(form);

        // Reset the form
        searchForm.clear();

        // Re-display the screen
        return display(mapping, form, request, response);
    }

    /**
     * Performs an undeliverable mail search based on the search criteria entered by the user.
     *
     * @param mapping An action mapping
     * @param form A form bean
     * @param request A http request from an search.jsp page
     * @param response A http response to stream data to a next page
     *
     * @return An action forward class encapsulating information about a next page
     * @throws Exception if any errors occurred while trying to process the person search.
     */
    public ActionForward search(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception
    {
        // ActionForward that defines where we will forward to next
        ActionForward forward = null;

        // If messages are present, add them to be displayed to the user and remove
        // the message keys from session so they won't be displayed again.
        processMessage(request, true);
        processMessage(request, false);

        // Ensure we have a valid search form
        UndeliverableMailSearchForm searchForm = getUndeliverableMailSearchForm(form);

        // Remove any unapplicable address fields from the search form
        removeUnapplicableAddressFields(searchForm);

        // Perform US extra validation
        if (Country.isUSAddress(searchForm.getCountry()))
        {
            // Validate the state
            if (!stateValid(searchForm, AddressForm.class, STATE_FIELD, null, request))
            {
                return mapping.findForward(FORWARD_DISPLAY);
            }
        }

        try
        {
            // Get the value list information
            ValueList valueList = ValueListActionUtils.getValueList(searchForm,
                request, UNDELIVERABLE_MAIL_SEARCH_TABLE_ID, UNDELIVERABLE_MAIL_SEARCH_ADAPTER);

            // Check if any results were found
            ValueListInfo info = valueList.getValueListInfo();
            if (info.getTotalNumberOfEntries() == 0)
            {
                // No results were found so generate an error and forward to the
                // failure page
                addActionMessage(request, new ActionMessage(
                    ApplicationConstants.MessageKeys.ERRORS_SEARCH_NORESULT));
                forward = mapping.findForward(FORWARD_DISPLAY);
            }
            else
            {
                // Backup the ValueListInfo into session and store the resultant ValueList on the request
                ValueListActionUtils
                    .setValueList(request, valueList, UNDELIVERABLE_MAIL_VALUELIST_REQUEST_KEY);

                // Forward to the search results page.
                forward = mapping.findForward(FORWARD_DISPLAY_SEARCH_RESULTS);
            }
        }
        catch (MaxRecordsExceededValueListException ex)
        {
            // The search exceeded the maximum number of records allowed so
            // generate an error and forward back to the display page.
            addActionMessage(request, new ActionMessage(
                ApplicationConstants.MessageKeys.ERRORS_MAX_RECORDS_EXCEEDED,
                new Integer(ex.getTotalRecords()), new Integer(ex.getRecordLimit())));
            forward = mapping.findForward(FORWARD_DISPLAY);
        }

        // Return the forward
        return forward;
    }

    protected void processMessage(HttpServletRequest request, boolean errorMessage)
    {
        String messageKey = getMessageFromSession(request.getSession(), errorMessage);
        if (!StringUtils.isEmpty(messageKey))
        {
            if (errorMessage)
            {
                addActionMessage(request, new ActionMessage(messageKey));
            }
            else
            {
                addInformationMessage(request, messageKey);
            }
            setMessageInSession(request.getSession(), null, errorMessage);
        }
    }
    /**
     * Initialize and get the Struts lookup dispatch method map hashmap.
     *
     * @return the method map
     * @see org.apache.struts.actions.LookupDispatchAction#getKeyMethodMap()
     */
    protected Map getKeyMethodMap()
    {
        Map map = new HashMap();
        map.put("button.display", "display");
        map.put("button.search", "search");
        map.put("button.clear", "reset");
        return map;
    }
}