/**
 * ServiceValidator.java
 * Created on Jun 30, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.web.validators;

import java.io.Serializable;
import java.util.regex.Pattern;

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.web.formbeans.service.ServiceForm;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.core.service.cache.ICacheService;

/**
 * @author Vlada Jakobac
 * 
 */
public class ServiceValidator {

	private static final Logger logger = Logger
			.getLogger(ServiceValidator.class);
	private static final int MAX_LENGTH_50 = 50;
	private static final int MAX_LENGTH_255 = 255;
	private static final int MAX_LENGTH_25 = 25;
	private static String CONTAINER_CACHE_SERVICE_NAME = "Container Cache";

	@SuppressWarnings("unchecked")
	public static boolean validateServiceField(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=createService")
				&& !request.getQueryString().equals("method=updateService"))
			return true;

		boolean isValid = true;

		ServiceForm serviceForm = (ServiceForm) obj;
		String specialCharacterList = ValidatorProperties.getProperty(ValidatorProperties.SPECIAL_CHARACTERS_LIST);
		
		if (field.getKey().equalsIgnoreCase("serviceName")) {
			if (serviceForm.getName() == null
					|| serviceForm.getName().trim().length() == 0) {
				msgs.add(field.getKey(), new ActionMessage(
						"Service name is required.", false));
				logger.warn("Service name is required.");
				isValid = false;
			} else {
				if (serviceForm.getName().trim().length() > MAX_LENGTH_50) {
					msgs.add(field.getKey(), new ActionMessage(
							"Service name cannot exceed " + MAX_LENGTH_50
									+ " characters.", false));
					logger.warn("Service name cannot exceed " + MAX_LENGTH_50
							+ " characters.");
					isValid = false;
				} 
				if (serviceForm.getName().trim().length() > 0 &&
						specialCharacterList != null && !specialCharacterList.equals("")){//check for special characters
					String specialCharacterPattern = ".*[" + specialCharacterList + "].*";
					logger.debug("specialCharacterPattern=" + specialCharacterPattern);
					if (Pattern.matches(specialCharacterPattern, serviceForm.getName().trim())){
						String errorMessage = "Service 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.SERVICE){
							if (container.getContainerName().trim().equals(serviceForm.getName().trim())){
								if (serviceForm.getId().equals("") || //new service
										container.getContainerId() != Long.parseLong(serviceForm.getId())){//not the service being updated
									msgs.add(field.getKey(), new ActionMessage("Service with the same name already exists.", false));
									logger.warn("Service with the same name already exists.");
									isValid = false;
									break;
								}							
							}						
						}										
					}
				}
			}
				
			 
		}

		if (field.getKey().equalsIgnoreCase("description")) {
			if (serviceForm.getDescription() != null
					&& serviceForm.getDescription().length() > MAX_LENGTH_255) {
				msgs.add(field.getKey(), new ActionMessage(
						"The description field cannot exceed " + MAX_LENGTH_255
								+ " characters.", false));
				logger.warn("The description field cannot exceed "
						+ MAX_LENGTH_255 + " characters.");
				isValid = false;
			}
		}
		
		if (field.getKey().equalsIgnoreCase("lookupKey")) {
			logger.debug("serviceForm.getId()="+serviceForm.getId()+".");
			logger.debug("serviceForm.getLookupKey()=" + serviceForm.getLookupKey() +".");
			if (serviceForm.getLookupKey() != null && !serviceForm.getLookupKey().equals("")) {
				if (serviceForm.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);
					for (Serializable key : containerCache.getKeys()) {
						IContainer container = containerCache.get(key);
						logger.debug("container.getContainerLookupKey()=" + container.getContainerLookupKey() +".");
						if (container.getContainerLookupKey() != null && 
								container.getContainerLookupKey().trim().equals(serviceForm.getLookupKey().trim())){
							if (serviceForm.getId().equals("") ||
									container.getContainerId() != Long.parseLong(serviceForm.getId())){
								String errorMessage = container.getContainerType() + " with the same lookup key already exists.";						
								msgs.add(field.getKey(), new ActionMessage(errorMessage, false));
								logger.warn(errorMessage);
								isValid = false;
								break;
							}								
						}	
												
					}				
				}

			}
		}

		return isValid;
	}

}
