// Package 
package gov.va.med.esr.ui.common.action;

// Java Classes
import java.io.PrintWriter;
import java.util.Calendar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// Library Classes
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.commons.lang.Validate;

// Framework Classes
import gov.va.med.fw.util.StringUtils;

// ESR Classes
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.ui.common.util.DateUtils;

/**
 * Action handler for Date/Time formatting.
 *
 * @author Andrew Pach
 * @version: 3.0
 */
public class FormatDateTimeAction extends AbstractAction
{
    // Request parameters
    public static final String DATE_TIME_PARAM = "dateTime";
    public static final String FIELD_NAME_PARAM = "fieldName";
    public static final String FORMAT_PATTERN_PARAM = "formatPattern";

    // XML Tags
    public static final String ROOT_ELEMENT_START = "<message>";
    public static final String ROOT_ELEMENT_END = "</message>";
    public static final String DATE_TIME_START = "<dateTime>";
    public static final String DATE_TIME_END = "</dateTime>";
    public static final String VALUE_START = "<value>";
    public static final String VALUE_END = "</value>";
    public static final String FIELD_NAME_START = "<fieldName>";
    public static final String FIELD_NAME_END = "</fieldName>";

    /**
     * Formats a date/time
     * @param mapping The ActionMapping
     * @param form The ActionForm
     * @param request The HttpServletRequest
     * @param response The HttpServletResponse
     * @return The ActionForward
     * @throws Exception if any problems were encountered
     */
    public ActionForward format(ActionMapping mapping, ActionForm form, HttpServletRequest request,
        HttpServletResponse response) throws Exception
    {
        // Get the optional unformatted date/time from the request
        String dateTime = request.getParameter(FormatDateTimeAction.DATE_TIME_PARAM);

        // Get the optional format from the request
        String format = request.getParameter(FormatDateTimeAction.FORMAT_PATTERN_PARAM);

        // Get the field name from the request
        String fieldName = request.getParameter(FormatDateTimeAction.FIELD_NAME_PARAM);

        // Ensure a field name was passed
        Validate.notNull(fieldName, "No field name was found on the format date/time request.");

        // Format the date/time and build the response XML
        String xml = buildResponseXml(getFormattedDateTime(dateTime, format), fieldName);

        // Write the XML to the response
        response.setContentType("text/xml");
        response.setHeader("Cache-Control","no-cache");
        PrintWriter out = response.getWriter();
        out.println(xml);
        out.flush();

        // Return null so Struts doesn't do anything
        return null;
    }

    /**
     * Gets a formatted date/time.
     * @param dateTime The unformatted date/time
     * @param format The format to use
     * @return The formatted date/time
     */
    protected String getFormattedDateTime(String dateTime, String format)
    {
        // Default to today's date/time
        ImpreciseDate impreciseDate = new ImpreciseDate(Calendar.getInstance());

        // If a date/time was entered, convert it to an imprecise date
        if (StringUtils.isNotEmpty(dateTime))
        {
            impreciseDate = DateUtils.getImpreciseDate(dateTime, true);
        }

        // Return the formatted date/time
        return DateUtils.format(impreciseDate, format);
    }

    /**
     * Builds the response XML message
     * @param dateTime The formatted date/time
     * @param fieldName The field name to return back to the caller
     * @return The response XML message
     */
    protected String buildResponseXml(String dateTime, String fieldName)
    {
        StringBuffer xml = new StringBuffer();
        xml.append(FormatDateTimeAction.ROOT_ELEMENT_START);
        if (StringUtils.isNotEmpty(dateTime))
        {
            // Enclose the formatted date/time in start and end tags so the caller can
            // easily determine that a formatted date/time is present
            xml.append(FormatDateTimeAction.DATE_TIME_START);
            xml.append(FormatDateTimeAction.VALUE_START);
            xml.append(dateTime);
            xml.append(FormatDateTimeAction.VALUE_END);
            xml.append(FormatDateTimeAction.FIELD_NAME_START);
            xml.append(fieldName);
            xml.append(FormatDateTimeAction.FIELD_NAME_END);
            xml.append(FormatDateTimeAction.DATE_TIME_END);
        }
        xml.append(FormatDateTimeAction.ROOT_ELEMENT_END);
        return xml.toString();
    }

    /**
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet()
    {
    }
}
