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

// Java classes
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

// Library classes
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;

// ESR classes
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.lookup.ReportFormat;
import gov.va.med.esr.common.model.lookup.ReportPeriodType;
import gov.va.med.esr.common.model.lookup.ReportRunFrequency;
import gov.va.med.esr.common.model.lookup.ReportScheduleType;
import gov.va.med.esr.common.report.data.ParameterConfig;
import gov.va.med.esr.ui.ApplicationConstants.MessageKeys;
import gov.va.med.esr.ui.common.util.DateUtils;
import gov.va.med.fw.util.StringUtils;

/**
 * Perform programatic validation for all the report actions.
 * @author Muddaiah Ranga
 * @version 1.0
 */
public class ReportValidator implements ReportConstants {

	public static final String CURRENT_MONTH_NOT_VALID = "errors.currentMonthNotValid";
	
	
    /**
     * Validates the registry information.
     * 
     * @param form the military service form.
     * @param request the request object.
     * 
     * @return the action messages.
     */
    protected static ActionErrors validate(ReportInfoForm actionForm, 
                                           HttpServletRequest request,
                                           ActionErrors errors) {
        ReportScheduleInfoForm form = (ReportScheduleInfoForm)actionForm;
        
        ServletContext context = request.getSession().getServletContext();
        Map parameterMap = (Map)context.getAttribute(REPORT_PARAMETER_CONFIG);
        
        if(errors == null) errors =  new ActionErrors();
        MessageResources messageResources = form.getResources(request);
        String reportId = form.getReportIdNoSpace();
 
        Map reportParamMap = (Map)parameterMap.get(reportId);
        if(reportParamMap != null) {
            
            // Validate Report Schedule Fields.
            if(StringUtils.equals(form.getTabName(),TAB_NAME_SCHEDULED_REPORTS)) {
                ReportValidator.validateReportSceduleParams(form,messageResources,errors);
            }
            if(StringUtils.equals(reportId,"EED10")) {
                if( (!StringUtils.equals(TAB_NAME_SCHEDULED_REPORTS,form.getTabName())) ||
                      StringUtils.equals(ReportRunFrequency.OTHER.getCode(),form.getGenerateReport()) ) {
                    ReportValidator.validateForEED10(form,messageResources,errors,reportParamMap);
                }
            }
            
            for(Iterator iter = reportParamMap.keySet().iterator(); iter.hasNext();) {
                String fieldName = (String)iter.next();
                ParameterConfig paramConfig = (ParameterConfig)reportParamMap.get(fieldName);

                if(paramConfig != null) {
                    boolean isRequiredField = paramConfig.isRequired();
                    boolean isFieldOptionalForScheduling = false;
                    boolean isFutureDateAllowed = paramConfig.isFutureDateAllowed();
                    if(StringUtils.equals(fieldName,REPORT_PARAM_FROM_DATE) || StringUtils.equals(fieldName,REPORT_PARAM_TO_DATE) || 
                       StringUtils.equals(fieldName,REPORT_PARAM_FROM_YEAR) || StringUtils.equals(fieldName,REPORT_PARAM_TO_YEAR) ||
                       StringUtils.equals(fieldName,REPORT_PARAM_AS_OF_DATE)) {

                        if(StringUtils.equals(TAB_NAME_SCHEDULED_REPORTS,form.getTabName())) {
                            isFieldOptionalForScheduling = true;
                            if(StringUtils.equals(ReportRunFrequency.OTHER.getCode(),form.getGenerateReport())) {
                                isFutureDateAllowed = true;
                            }
                        }
                    }
                    
                    //Perform required field validation.
                    if(isRequiredField && (!isProvided(form,fieldName))) {
                        if(isFieldOptionalForScheduling) {
                            if(StringUtils.equals(ReportRunFrequency.OTHER.getCode(),form.getGenerateReport())) {
                                errors.add(fieldName,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(paramConfig.getLabel())));
                            }
                        } else {
                            errors.add(fieldName,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(paramConfig.getLabel())));
                        }
                    }
                    
                    //If the field type "date" perform date validation.
                    String fieldValue = getFieldValueAsString(form,fieldName);
                    if(StringUtils.isNotEmpty(fieldValue) && paramConfig.isDate()) {
                    	if (paramConfig.isPreciseDate()) {
                            validateDate(fieldValue,fieldName,isFutureDateAllowed,messageResources.getMessage(paramConfig.getLabel()),errors);
                    	} else {
                            boolean isMonthRequired = (StringUtils.equals(reportId,"EED10")) ? true : false;
                    		validateImpreciseDate(fieldValue,fieldName,isFutureDateAllowed,isMonthRequired,messageResources.getMessage(paramConfig.getLabel()),errors);
                    	} 
                    }
                }
                
                //Validate fromDate and toDate Fields
                if(StringUtils.equals(fieldName,REPORT_PARAM_TO_YEAR)) {
                    validateFromAndToYears(form, reportParamMap, messageResources, errors);
                }
                
                //Validate fromDate and toDate Fields
                if(StringUtils.equals(fieldName,REPORT_PARAM_TO_DATE)) {
                    validateFromAndToDates(form, reportParamMap, messageResources, errors);
                }

                if(StringUtils.equals(fieldName,REPORT_PARAM_FACILITIES) && StringUtils.isNotEmpty(form.getFacilityDisplayByNoDefault())) {
                    if(!isProvided(form,fieldName)) {
                        errors.add(fieldName,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(paramConfig.getLabel())));
                    }
                }
                
            }     
        }       
        validateStartAndEndIncomeYears(form, reportParamMap, messageResources, errors);       
                
        if(StringUtils.equals(reportId,"QM10")) {
            ReportValidator.validateForQM10(form,messageResources,errors);
        }       
        
        if(StringUtils.equals(reportId,"QM17")) {
            if(StringUtils.equals(form.getReportFormat(),ReportFormat.DETAIL.getCode())) {
                if(!isProvided(form,REPORT_PARAM_REPORT_DETAIL_BY)) {
                    errors.add(REPORT_PARAM_REPORT_DETAIL_BY,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_REPORT_DETAIL_BY)));
                }
            }
        }  
        
        return errors;
    }

    private static boolean isProvided(ReportScheduleInfoForm form,String fieldName) {
        try { 
            Object object = getFieldValue(form,fieldName);
            if(object == null || object instanceof String && StringUtils.isEmpty(((String)object).trim()) || object instanceof String[] && ((String[])object).length == 0) {
                return false;
            }
        } catch(Exception ex) {
            throw new RuntimeException(ex);
        }
        return true;
    }
    
    private static Object getFieldValue(ReportScheduleInfoForm form,String fieldName) {
        try { 
            PropertyUtilsBean propertyUtils = new PropertyUtilsBean();
            return propertyUtils.getNestedProperty(form,fieldName);
        } catch(Exception ex) {
            throw new RuntimeException(ex);
        }
    }
    
    private static String getFieldValueAsString(ReportScheduleInfoForm form,String fieldName) {
        try { 
            PropertyUtilsBean propertyUtils = new PropertyUtilsBean();
            Object object = propertyUtils.getNestedProperty(form,fieldName);
            return (object != null && object instanceof String) ? StringUtils.trim((String)object) : null;
        } catch(Exception ex) {
            throw new RuntimeException(ex);
        }
    }
        
    private static void validateFromAndToYears(ReportScheduleInfoForm form, Map reportParamMap, MessageResources messageResources, ActionErrors errors) {
    	if (StringUtils.isNotEmpty(form.getFromYear()) && StringUtils.isNotEmpty(form.getToYear())) {
	    	try {
		    	int fromYear = Integer.parseInt(form.getFromYear());
		        int toYear = Integer.parseInt(form.getToYear());
		        
		        if (fromYear > 0 && toYear > 0 && fromYear > toYear) {
		            ParameterConfig fromDateParamConfig = (ParameterConfig)reportParamMap.get(REPORT_PARAM_FROM_YEAR);
		            ParameterConfig toDateParamConfig = (ParameterConfig)reportParamMap.get(REPORT_PARAM_TO_YEAR);	        	
	                errors.add(REPORT_PARAM_TO_YEAR,new ActionMessage(ERROR_INVALID_START_END_DATES,messageResources.getMessage(toDateParamConfig.getLabel()),messageResources.getMessage(fromDateParamConfig.getLabel())));
		        }
	        }catch (NumberFormatException e){
	        	//Ignore the error as imprecise date validation will catch it
	        }
    	}
    }
    
    private static void validateStartAndEndIncomeYears(ReportScheduleInfoForm form, Map reportParamMap, MessageResources messageResources, ActionErrors errors) {
    	if (StringUtils.isNotEmpty(form.getBeginIncomeYear()) && StringUtils.isNotEmpty(form.getEndIncomeYear())) {
	    	try {
		    	int startIncomeYear = Integer.parseInt(form.getBeginIncomeYear());
		        int endIncomeYear = Integer.parseInt(form.getEndIncomeYear());
		        
		        if (startIncomeYear > 0 && endIncomeYear > 0 && startIncomeYear > endIncomeYear) {
		            ParameterConfig startIncomeYearParamConfig = (ParameterConfig)reportParamMap.get(REPORT_PARAM_BEGIN_INCOME_YEAR);
		            ParameterConfig endIncomeYearParamConfig = (ParameterConfig)reportParamMap.get(REPORT_PARAM_END_INCOME_YEAR);	        	
	                errors.add(REPORT_PARAM_END_INCOME_YEAR,new ActionMessage(ERROR_INVALID_START_END_DATES,messageResources.getMessage(endIncomeYearParamConfig.getLabel()),messageResources.getMessage(startIncomeYearParamConfig.getLabel())));
		        }
	        }catch (NumberFormatException e){
	        	//Ignore the error as imprecise date validation will catch it
	        }
    	}
    }
    private static void validateFromAndToDates(ReportScheduleInfoForm form, Map reportParamMap, MessageResources messageResources, ActionErrors errors) {
        //Validate fromDate and toDate Fields
        Date fromDate = getDate(form.getFromDate());
        Date toDate = getDate(form.getToDate());
        if(fromDate != null && toDate != null) {
            ParameterConfig fromDateParamConfig = (ParameterConfig)reportParamMap.get(REPORT_PARAM_FROM_DATE);
            ParameterConfig toDateParamConfig = (ParameterConfig)reportParamMap.get(REPORT_PARAM_TO_DATE);
            if(fromDateParamConfig != null && toDateParamConfig != null) {
                if(fromDate.after(toDate)) {
                    errors.add(REPORT_PARAM_TO_DATE,new ActionMessage(ERROR_INVALID_START_END_DATES,                    		
                    		messageResources.getMessage(toDateParamConfig.getLabel()),
                    		messageResources.getMessage(fromDateParamConfig.getLabel())));
                }              
            }
            
            //validate the date range if defined
            if (toDateParamConfig.getDateRangeInDays() > 0){
                if (!isDatesInRange(fromDate,toDate,toDateParamConfig.getDateRangeInDays())){
                    errors.add(REPORT_PARAM_TO_DATE,
                        new ActionMessage(ERROR_INVALID_DATE_RANGE,
                                new Integer(toDateParamConfig.getDateRangeInDays())));                                                 
                }
            }
        }
    }
    
    private static boolean isDatesInRange(Date startDate, Date endDate, int dateRangeInDays) {
        Long days = (startDate != null && endDate != null) ? DateUtils.getDays(startDate,endDate) : null;
        return (days != null && days.longValue() <= dateRangeInDays) ? true : false;
    }

    private static void validateForEED10(ReportScheduleInfoForm form, 
                                        MessageResources messageResources,
                                        ActionErrors errors,
                                        Map reportParamMap) {
        String fromDate = form.getFromDate();
        String toDate = form.getToDate();
        String asOfDate = form.getAsOfDate();
        
        if(StringUtils.isNotEmpty(fromDate) && StringUtils.isEmpty(toDate)) {
            ParameterConfig paramConfig = (ParameterConfig)reportParamMap.get(REPORT_PARAM_TO_DATE);
            errors.add(REPORT_PARAM_TO_DATE,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(paramConfig.getLabel())));
            return;
        }
        
        if(StringUtils.isEmpty(fromDate) && StringUtils.isNotEmpty(toDate)) {
            ParameterConfig paramConfig = (ParameterConfig)reportParamMap.get(REPORT_PARAM_FROM_DATE);
            errors.add(REPORT_PARAM_FROM_DATE,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(paramConfig.getLabel())));
            return;
        }
        
        if(StringUtils.isEmpty(fromDate) && StringUtils.isEmpty(toDate) && StringUtils.isEmpty(asOfDate)) {
            //Either (From and To Dates) Or As Of Date is required.
            errors.add(REPORT_PARAM_FROM_DATE,new ActionMessage(ERROR_EITHER_FROM_AND_TO_DATE_OR_AS_OF_DATE_REQUIRED));
            errors.add(REPORT_PARAM_TO_DATE,new ActionMessage(ERROR_EITHER_FROM_AND_TO_DATE_OR_AS_OF_DATE_REQUIRED));
            errors.add(REPORT_PARAM_AS_OF_DATE,new ActionMessage(ERROR_EITHER_FROM_AND_TO_DATE_OR_AS_OF_DATE_REQUIRED));
            return;
        }
        
        if((StringUtils.isNotEmpty(fromDate) || StringUtils.isNotEmpty(toDate)) && StringUtils.isNotEmpty(asOfDate)) {
            //As Of Date is not allowed.
            errors.add(REPORT_PARAM_FROM_DATE,new ActionMessage(ERROR_BOTH_FROM_AND_TO_DATE_AND_AS_OF_DATE_NOT_ALLOWED)); 
            errors.add(REPORT_PARAM_TO_DATE,new ActionMessage(ERROR_BOTH_FROM_AND_TO_DATE_AND_AS_OF_DATE_NOT_ALLOWED));
            errors.add(REPORT_PARAM_AS_OF_DATE,new ActionMessage(ERROR_BOTH_FROM_AND_TO_DATE_AND_AS_OF_DATE_NOT_ALLOWED));
            return;
        }
    }
    
    private static void validateForQM10(ReportScheduleInfoForm form, 
                                        MessageResources messageResources,
                                        ActionErrors errors) {
        String reportPeriodType = form.getReportPeriodType();
        boolean isFutureDateAllowed = false;
        if(StringUtils.equals(reportPeriodType,ReportPeriodType.CODE_DATE_RANGE.getCode())) {
            boolean isFromAndToDateRequired = true;
            //Date range from and to dates are required for on demand reports and scheduled reports only with OTHER option.
            if(StringUtils.equals(TAB_NAME_SCHEDULED_REPORTS,form.getTabName())) {
                isFromAndToDateRequired = (StringUtils.equals(ReportRunFrequency.OTHER.getCode(),form.getGenerateReport())) ? true : false;
                isFutureDateAllowed = true;
            } 
            if(isFromAndToDateRequired) {
                if(!isProvided(form,REPORT_PARAM_REPORT_PERIOD_START_DATE)) {
                        errors.add(REPORT_PARAM_REPORT_PERIOD_START_DATE,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_REPORT_PERIOD_FROM)));
                }
                if(!isProvided(form,REPORT_PARAM_REPORT_PERIOD_END_DATE)) {
                        errors.add(REPORT_PARAM_REPORT_PERIOD_END_DATE,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_REPORT_PERIOD_TO)));
                }
            }
            Calendar calendar = Calendar.getInstance();
            calendar.clear();
            calendar.set(2002, 9, 1);
            
            Date fromDate = getDate(form.getReportPeriodStartDate());
            Date toDate = getDate(form.getReportPeriodEndDate());
            validateDate(form.getReportPeriodStartDate(),REPORT_PARAM_REPORT_PERIOD_START_DATE,isFutureDateAllowed,
            messageResources.getMessage(LABEL_REPORT_PERIOD_FROM),errors);
            validateDate(form.getReportPeriodEndDate(),REPORT_PARAM_REPORT_PERIOD_END_DATE,isFutureDateAllowed,
            messageResources.getMessage(LABEL_REPORT_PERIOD_TO),errors);
            if(fromDate != null && fromDate.compareTo(calendar.getTime()) < 0) {
                errors.add(REPORT_PARAM_REPORT_PERIOD_START_DATE,new ActionMessage(ERROR_INVALID_FROM_DATE,
                        DateUtils.format(calendar.getTime(), DateUtils.MMDDYYYY)));
            }
            if(fromDate!=null && toDate!=null && fromDate.after(toDate)) {
                errors.add(REPORT_PARAM_REPORT_PERIOD_END_DATE,new ActionMessage(ERROR_INVALID_START_END_DATES,                         
                        messageResources.getMessage(LABEL_REPORT_PERIOD_TO),
                        messageResources.getMessage(LABEL_REPORT_PERIOD_FROM)));
            } 
        }
        //All fiscal years as of date
        else if(StringUtils.equals(reportPeriodType,ReportPeriodType.CODE_ALL_FISCAL_YEARS.getCode())) {
            if(!isProvided(form,REPORT_PARAM_AS_OF_DATE)) {
                errors.add(REPORT_PARAM_AS_OF_DATE,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_REPORT_AS_OF_DATE)));
            }
            else {
                validateDate(form.getAsOfDate(),REPORT_PARAM_AS_OF_DATE,false,
                messageResources.getMessage(LABEL_REPORT_AS_OF_DATE),errors);
            }            
        }
        //Report fiscal year and quarterly report fiscal year are defauled to current fiscal year    
    }
    
    private static void validateReportSceduleParams(ReportScheduleInfoForm form, 
                                                    MessageResources messageResources,
                                                    ActionErrors errors) {
        if(!isProvided(form,REPORT_PARAM_GENERATE_REPORT)) {
            errors.add(REPORT_PARAM_GENERATE_REPORT,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_GENERATE_REPORT)));
        } else {
            String generateReport = form.getGenerateReport();
            String scheduleType = form.getScheduleType();
            if(StringUtils.equals(generateReport,ReportRunFrequency.DAILY_WEEKLY.getCode())) {
                if(!isProvided(form,REPORT_PARAM_DAILY_WEEKLY_DAY)) {
                    errors.add(REPORT_PARAM_DAILY_WEEKLY_DAY,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_DAY_TO_GENERATE_REPORT)));
                }
            } else if(StringUtils.equals(generateReport,ReportRunFrequency.MONTHLY.getCode())) {
                
                if( StringUtils.equals(scheduleType,ReportScheduleType.DAY_OF_MONTH.getCode()) ||
                    StringUtils.equals(scheduleType,ReportScheduleType.WEEK_DAY.getCode()) ) {
                } else {
                    errors.add(REPORT_PARAM_SCHEDULE_TYPE,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_DAY_TO_GENERATE_REPORT)));
                }
                    
            } else if(StringUtils.equals(generateReport,ReportRunFrequency.YEARLY.getCode())) {
                
                if( StringUtils.equals(scheduleType,ReportScheduleType.WEEK_DAY_MONTH.getCode()) ||
                    StringUtils.equals(scheduleType,ReportScheduleType.MONTH_DAY.getCode()) ) {
                    if(StringUtils.equals(scheduleType,ReportScheduleType.MONTH_DAY.getCode())) {
                        if(!isProvided(form,REPORT_PARAM_YEARLY_DAY_OF_MONTH)) {
                            errors.add(REPORT_PARAM_SCHEDULE_TYPE,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_DAY_TO_MONTH)));
                        }
                    }
                } else {
                    errors.add(REPORT_PARAM_SCHEDULE_TYPE,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_DAY_TO_GENERATE_REPORT)));
                }
                
            } else if(StringUtils.equals(generateReport,ReportRunFrequency.OTHER.getCode())) {
                if(!isProvided(form,REPORT_PARAM_OTHER_DATE_TO_GENERATE_REPORT)) {
                    errors.add(REPORT_PARAM_OTHER_DATE_TO_GENERATE_REPORT,new ActionMessage(MessageKeys.ERRORS_REQUIRED,messageResources.getMessage(LABEL_DATE_TO_GENERATE_REPORT)));
                } else {
                    Date dateToGenerate = getDate(form.getOtherDateToGenerateReport(),form.getTimeToGenerateReportHourNoDefault(),form.getTimeToGenerateReportMinuteNoDefault());
                    if(dateToGenerate != null && dateToGenerate.before(DateUtils.getCurrentDateTime())) {
                        errors.add(REPORT_PARAM_OTHER_DATE_TO_GENERATE_REPORT,new ActionMessage(ERROR_DATE_NO_PAST,messageResources.getMessage(LABEL_DATE_TO_GENERATE_REPORT)));
                    }
                }
            }
            ReportValidator.validateEmail(form,messageResources,errors);
        }     
    }
    
    /**
     * Validate the date for the correct format.
     * 
     * @param fieldValue the date field value
     * @param fieldName the field name
     * @param fieldLabel field label
     * @param errors the validation error object
     */
    private static boolean validateDate(String fieldValue,String fieldName,boolean isFutureDateAllowed, String fieldLabel,ActionMessages errors)
    {
        boolean isValid = true;
        if(StringUtils.isNotEmpty(fieldValue)) {
            try {
                Date date = DateUtils.getDate(fieldValue);
                if(date != null && (!isFutureDateAllowed) && date.after(new Date())) {
                    isValid = false;
                    errors.add(fieldName,new ActionMessage(MessageKeys.ERRORS_INVALID_FURUTE_DATE,fieldLabel));
                }
            } catch (Exception ex) {
                isValid = false;
                errors.add(fieldName,new ActionMessage(MessageKeys.ERRORS_INVALID,fieldLabel));
            }
        }
        return isValid;
    }

    private static boolean validateImpreciseDate(String fieldValue,String fieldName,boolean isFutureDateAllowed, boolean isMonthRequired, String fieldLabel,ActionMessages errors)
    {
        boolean isValid = true;
        if(StringUtils.isNotEmpty(fieldValue)) {
            try {
                ImpreciseDate date = DateUtils.getImpreciseDate(fieldValue);
                if(date != null && (!isFutureDateAllowed)) {
                	Calendar currDate = Calendar.getInstance();
                	Calendar dateValue = date.getCalendar();
                	if (currDate.getTime().before(dateValue.getTime())) {
                		isValid = false;
                		errors.add(fieldName,new ActionMessage(MessageKeys.ERRORS_INVALID_FURUTE_DATE,fieldLabel));
                	}
                }
                if(date != null && isValid && isMonthRequired && date.isMonthPrecise() == false) {
                    isValid = false;
                    errors.add(fieldName,new ActionMessage(ERROR_INVALID_IMPRECISE_DATE_WITH_MONTH,fieldLabel));
                }
            } catch (Exception ex) {
                isValid = false;
                errors.add(fieldName,new ActionMessage(MessageKeys.ERRORS_INVALID,fieldLabel));
            }
            
        }
        return isValid;
    }
    
    private static Date getDate(String fieldValue) {
        if(StringUtils.isNotEmpty(fieldValue)) {
            try {
                 return DateUtils.getDate(fieldValue);
            } catch (Exception ex) {
                //Ignore the exceptions
            }
        }
        return null;
    }
    
    private static Date getDate(String date, String hours, String minutes) {
        Date dt = ReportValidator.getDate(date);
        Calendar cal = null;
        if(dt != null) {
            cal = Calendar.getInstance();
            cal.clear();
            cal.setTime(dt);
            int hrs = (StringUtils.isNotEmpty(hours)) ? Integer.parseInt(hours) : 0;
            int mns = (StringUtils.isNotEmpty(minutes)) ? Integer.parseInt(minutes) : 0;
            cal.set(Calendar.HOUR,hrs);
            cal.set(Calendar.MINUTE,mns);
        }
        return (cal != null) ? cal.getTime() : null;
        
    }
    
    private static void validateEmail(ReportScheduleInfoForm form, 
                                      MessageResources messageResources,
                                      ActionErrors errors) {
        String emailReportTo = form.getEmailReportTo();
        Pattern pat = Pattern.compile(EMAIL_REG_EXPR,Pattern.CASE_INSENSITIVE);
        if(StringUtils.isNotEmpty(emailReportTo)) {
            String[] emails = StringUtils.split(emailReportTo,EMAIL_DELIMS);
            for(int i=0; i<emails.length; i++) {
                String email = StringUtils.trim(emails[i]);
                if(StringUtils.isNotEmpty(email)) {
                    if(!pat.matcher(email).find()) { 
                        errors.add(REPORT_PARAM_EMAIL_REPORT_TO,new ActionMessage(ERROR_INVALID_EMAIL,messageResources.getMessage(LABEL_EMAIL_REPORT_TO)));
                        return;
                    }
                }
            }
        }
    }
}
