/**
 * PartnerValidator.java
 * Created on Jun 16, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.web.validators;

import java.io.Serializable;
import java.util.regex.Pattern;

import javax.mail.internet.InternetAddress;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionMessage;

import com.tandbergtv.watchpoint.pmm.entities.ContainerType;
import com.tandbergtv.watchpoint.pmm.entities.IContainer;
import com.tandbergtv.watchpoint.pmm.entities.Partner;
import com.tandbergtv.watchpoint.pmm.web.formbeans.partner.PartnerForm;
import com.tandbergtv.watchpoint.pmm.web.util.PartnerFormPopulator;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.core.service.cache.ICacheService;

/**
 * @author Vlada Jakobac
 *
 */
public class PartnerValidator {

	private static final int MAX_LENGTH_25 = 25;
	private static final Logger logger = Logger.getLogger(PartnerValidator.class);
	private static final int MAX_LENGTH_50 = 50;
	private static final int MAX_LENGTH_500 = 500;
	private static String CONTAINER_CACHE_SERVICE_NAME = "Container Cache";
	
	@SuppressWarnings("unchecked")
	public static boolean validatePartnerField(java.lang.Object obj,
			org.apache.commons.validator.ValidatorAction action,
			org.apache.commons.validator.Field field, org.apache.struts.action.ActionMessages msgs,
			org.apache.commons.validator.Validator validator,
			javax.servlet.http.HttpServletRequest request) {
		if (!request.getQueryString().equals("method=createPartner") && !request.getQueryString().equals("method=updatePartner"))
			return true;
		
		boolean isValid = true;
		
		
		PartnerForm partnerForm = (PartnerForm) obj;
		String specialCharacterList = ValidatorProperties.getProperty(ValidatorProperties.SPECIAL_CHARACTERS_LIST);
		
		if (field.getKey().equalsIgnoreCase("partnerName")) {
			logger.debug("partnerForm.getName()="+partnerForm.getName()+".");
			logger.debug("partnerForm.getId()="+partnerForm.getId());
			if (partnerForm.getName() == null || partnerForm.getName().trim().length() == 0) {
				msgs.add(field.getKey(), new ActionMessage("Partner name is required.", false));
				logger.warn("Partner name is required.");
				isValid = false;
			} else {
				if (partnerForm.getName().trim().length() > MAX_LENGTH_25){
					msgs.add(field.getKey(), new ActionMessage("Partner name cannot exceed " + MAX_LENGTH_25 + " characters.", false));
					logger.warn("Partner name cannot exceed " + MAX_LENGTH_25 + " characters.");
					isValid = false;
				}
				if (partnerForm.getName().trim().length() > 0 &&
						specialCharacterList != null && !specialCharacterList.equals("")){//check for special characters
					String specialCharacterPattern = ".*[" + specialCharacterList + "].*";
					logger.debug("specialCharacterPattern=" + specialCharacterPattern);
					if (Pattern.matches(specialCharacterPattern, partnerForm.getName().trim())){
						String errorMessage = "Partner name cannot contain any of the following characters:" + specialCharacterList; 
						msgs.add(field.getKey(), new ActionMessage(errorMessage, false));
						logger.warn(errorMessage);
						isValid = false;
					}
				}
				if (isValid){
					//check for duplicates
					ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
					.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
					for (Serializable key : containerCache.getKeys()) {
						IContainer container = containerCache.get(key);
						logger.debug("container.getContainerName()="+container.getContainerName());
						if (container.getContainerType() == ContainerType.PARTNER){
							if (container.getContainerName().trim().equals(partnerForm.getName().trim())){
								if (partnerForm.getId().equals("") || //new partner
										container.getContainerId() != Long.parseLong(partnerForm.getId())){//not the partner being updated
									msgs.add(field.getKey(), new ActionMessage("Partner with the same name already exists.", false));
									logger.warn("Partner with the same name already exists.");
									isValid = false;
									break;
								}							
							}						
						}										
					}
				}
			}		
		}
		
		if (field.getKey().equalsIgnoreCase("providerId")) {
			if (partnerForm.getProviderId() == null
					|| partnerForm.getProviderId().trim().length() == 0) {
				msgs.add(field.getKey(), new ActionMessage(
						"Provider Id is required.", false));
				logger.warn("Provider Id is required.");
				isValid = false;
			} else {
				if (partnerForm.getProviderId().trim().length() > MAX_LENGTH_25){
					msgs.add(field.getKey(), new ActionMessage("Provider Id cannot exceed " + MAX_LENGTH_25 + " characters.", false));
					logger.warn("Provider Id cannot exceed " + MAX_LENGTH_25 + " characters.");
					isValid = false;
				} 
				if (partnerForm.getProviderId().trim().length() > 0 &&
						specialCharacterList != null && !specialCharacterList.equals("")){//check for special characters
					String specialCharacterPattern = ".*[" + specialCharacterList + "].*";
					logger.debug("specialCharacterPattern=" + specialCharacterPattern);
					if (Pattern.matches(specialCharacterPattern, partnerForm.getProviderId().trim())){
						String errorMessage = "Provider Id cannot contain any of the following characters:" + specialCharacterList;
						msgs.add(field.getKey(), new ActionMessage(errorMessage, false));
						logger.warn(errorMessage);
						isValid = false;
					}
				}
				if (isValid){
					//check for duplicates
					ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
					.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
					for (Serializable key : containerCache.getKeys()) {
						IContainer container = containerCache.get(key);
						if (container.getContainerType() == ContainerType.PARTNER){
							String providerId = ((Partner)container).getProviderId();
							
							if (providerId.trim().equals(partnerForm.getProviderId().trim())){ 
								if (partnerForm.getId().equals("") || //new partner
										container.getContainerId() != Long.parseLong(partnerForm.getId())){//not the partner being updated
									msgs.add(field.getKey(), new ActionMessage("Partner with the same Provider Id already exists.", false));
									logger.warn("Partner with the same Provider Id already exists.");
									isValid = false;
									break;
								}
							}
						}						
					}
				}		
			}
		}
		
		if (field.getKey().equalsIgnoreCase("firstName")) {
			if (partnerForm.getFirstName() != null
					&& partnerForm.getFirstName().trim().length() > MAX_LENGTH_25) {
				msgs.add(field.getKey(), new ActionMessage(
						"The contact's first name cannot exceed " + MAX_LENGTH_25 + " characters.", false));
				logger.warn("The contact's first name cannot exceed " + MAX_LENGTH_25 + " characters.");
				isValid = false;
			} else if (partnerForm.getFirstName().trim().length() > 0){//check for non-numeric characters
				if (Pattern.matches(".*\\d.*",partnerForm.getFirstName().trim())){
					msgs.add(field.getKey(), new ActionMessage(
							"The contact's first name cannot contain numerical characters.", false));
					logger.warn("The contact's first name cannot contain numerical characters.");
					isValid = false;
				}
			}
		}

		if (field.getKey().equalsIgnoreCase("lastName")) {
			if (partnerForm.getLastName() != null
					&& partnerForm.getLastName().trim().length() > MAX_LENGTH_25) {
				msgs.add(field.getKey(), new ActionMessage(
						"The contact's last name cannot exceed " + MAX_LENGTH_25 + " characters.", false));
				logger.warn("The contact's last name cannot exceed " + MAX_LENGTH_25 + " characters.");
				isValid = false;
			} else if (partnerForm.getLastName().trim().length() > 0){//check for non-numeric characters
				if (Pattern.matches(".*\\d.*",partnerForm.getLastName().trim())){
					msgs.add(field.getKey(), new ActionMessage(
							"The contact's last name cannot contain numerical characters.", false));
					logger.warn("The contact's last name cannot contain numerical characters.");
					isValid = false;
				}
			}
		}
		
		if (field.getKey().equalsIgnoreCase("email")) {
			String email = partnerForm.getEmail();
			if (email == null || email.trim().length() == 0) {
				msgs.add(field.getKey(), new ActionMessage(
						"The contact's email is required.", false));
				logger.warn("The contact's email is required.");
				isValid = false;
			} else {
				if (email.trim().length() > MAX_LENGTH_50){
					msgs.add(field.getKey(), new ActionMessage("The contact's email cannot exceed " + MAX_LENGTH_50 + " characters.", false));
					logger.warn("The contact's email cannot exceed " + MAX_LENGTH_50 + " characters.");
					isValid = false;
				} 
				try	{
					new InternetAddress(email, true);
				} catch (Exception ex) {
					msgs.add(field.getKey(), new ActionMessage(
							"The contact's email is invalid.", false));
					logger.warn("The contact's email is invalid.");
					isValid = false;
				}				
			}
		}
		
		if (field.getKey().equalsIgnoreCase("defaultPitchFreqWeeks")) {
			if (partnerForm.getDefaultPitchFreqWeeks()!=null && 
					!partnerForm.getDefaultPitchFreqWeeks().trim().equals("")){
				try {
					int weeks =  new Integer(partnerForm.getDefaultPitchFreqWeeks()).intValue();
					if (weeks<1 || weeks>52){
						msgs.add(field.getKey(), new ActionMessage(
								"The 'weeks' value for the default pitch frequency should be between 1 and 52.", false));
						logger.warn("The 'weeks' value for the default pitch frequency should be between 1 and 52.");
						isValid = false;
					}
				} catch (Exception ex){
					msgs.add(field.getKey(), new ActionMessage(
							"The 'weeks' value for the default pitch frequency is not a number.", false));
					logger.warn("The 'weeks' value for the default pitch frequency is not a number.");
					isValid = false;
				}
			}			
		}
		
		if (field.getKey().equalsIgnoreCase("notes")) {
			if (partnerForm.getNotes() != null
					&& partnerForm.getNotes().length() > MAX_LENGTH_500) {
				msgs.add(field.getKey(), new ActionMessage(
						"The Notes field cannot exceed " + MAX_LENGTH_500
								+ " characters.", false));
				logger.warn("The Notes field cannot exceed "
						+ MAX_LENGTH_500 + " characters.");
				isValid = false;
			} 
		}
		
		if (field.getKey().equalsIgnoreCase("lookupKey")) {
			logger.debug("partnerForm.getLookupKey()=" + partnerForm.getLookupKey() +".");
			if (partnerForm.getLookupKey() != null && !partnerForm.getLookupKey().equals("")){
				if (partnerForm.getLookupKey().length() > MAX_LENGTH_25) {
					msgs.add(field.getKey(), new ActionMessage(
							"The Lookup Key field cannot exceed " + MAX_LENGTH_25
									+ " characters.", false));
					logger.warn("The Lookup Key field cannot exceed "
							+ MAX_LENGTH_25 + " characters.");
					isValid = false;
				} else {//check for duplicates
					ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
					.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
					logger.debug("containerCache.count()=" + containerCache.count());
					for (Serializable key : containerCache.getKeys()) {
						IContainer container = containerCache.get(key);
						logger.debug("container.getContainerLookupKey()=" + container.getContainerLookupKey() +".");
						if (container.getContainerLookupKey() != null && 
								container.getContainerLookupKey().trim().equals(partnerForm.getLookupKey().trim())){							
							if (partnerForm.getId().equals("") ||
									container.getContainerId() != Long.parseLong(partnerForm.getId())){
								String errorMessage = container.getContainerType() + " with the same lookup key already exists.";						
								logger.warn(errorMessage);
								msgs.add(field.getKey(), new ActionMessage(errorMessage, false));								
								isValid = false;
								break;
							}
							
						}	
												
					}				
				}
			}
			
		}
		PartnerFormPopulator.setRequiredInfoInForm(request, partnerForm);

		return isValid;
	}

}
