/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.ecview.core.common.editpart.emf.datatypes;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeBridge;
import org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.emf.validation.RegexpValidatorEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.validation.IBeanValidationValidatorEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.validation.IMaxLengthValidatorEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.validation.IMinLengthValidatorEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.validation.IRegexpValidatorEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.validation.IValidatorEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YElement;
import org.eclipse.osbp.ecview.core.common.model.validation.ValidationFactory;
import org.eclipse.osbp.ecview.core.common.model.validation.ValidationPackage;
import org.eclipse.osbp.ecview.core.common.model.validation.YBeanValidationValidator;
import org.eclipse.osbp.ecview.core.common.model.validation.YBeanValidationValidatorConfig;
import org.eclipse.osbp.ecview.core.common.model.validation.YMaxLengthValidationConfig;
import org.eclipse.osbp.ecview.core.common.model.validation.YMaxLengthValidator;
import org.eclipse.osbp.ecview.core.common.model.validation.YMinLengthValidationConfig;
import org.eclipse.osbp.ecview.core.common.model.validation.YMinLengthValidator;
import org.eclipse.osbp.ecview.core.common.model.validation.YRegexpValidationConfig;
import org.eclipse.osbp.ecview.core.common.model.validation.YRegexpValidator;
import org.eclipse.osbp.ecview.core.common.model.validation.YValidationConfig;
import org.eclipse.osbp.ecview.core.common.model.validation.YValidator;
import org.eclipse.osbp.ecview.core.common.validation.IValidationConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// TODO: Auto-generated Javadoc
/**
 * A temporary factory. It should be replaced by OSGi services later.
 */
public class ValidatorByConfigFactory {

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory
			.getLogger(ValidatorByConfigFactory.class);

	/**
	 * Creates a new minLengthValidator.
	 *
	 * @param config
	 *            the config
	 * @return the i min length validator editpart
	 */
	public static IMinLengthValidatorEditpart createMinLengthValidator(
			IValidationConfig config) {
		YMinLengthValidationConfig yValidationConfig = (YMinLengthValidationConfig) config
				.getValidationSettings();
		IMinLengthValidatorEditpart editpart = null;
		int minlength = yValidationConfig.getMinLength();
		if (minlength > 0) {
			YMinLengthValidator yValidator = ValidationFactory.eINSTANCE
					.createYMinLengthValidator();
			yValidator.setMinLength(minlength);
			editpart = ElementEditpart.getEditpart(config.getContext(), yValidator);
			editpart.setConfig(config);
		}
		return editpart;
	}

	/**
	 * Creates a new maxLengthValidator.
	 *
	 * @param config
	 *            the config
	 * @return the i max length validator editpart
	 */
	public static IMaxLengthValidatorEditpart createMaxLengthValidator(
			IValidationConfig config) {
		YMaxLengthValidationConfig yValidationConfig = (YMaxLengthValidationConfig) config
				.getValidationSettings();
		IMaxLengthValidatorEditpart editpart = null;
		int maxlength = yValidationConfig.getMaxLength();
		if (maxlength > 0) {
			YMaxLengthValidator yValidator = ValidationFactory.eINSTANCE
					.createYMaxLengthValidator();
			yValidator.setMaxLength(maxlength);
			editpart = getEditpart(config.getContext(), yValidator);
			editpart.setConfig(config);
		}
		return editpart;
	}

	/**
	 * Creates a new regExpressionValidator.
	 *
	 * @param config
	 *            the config
	 * @return the i regexp validator editpart
	 */
	public static IRegexpValidatorEditpart createRegExpressionValidator(
			IValidationConfig config) {
		YRegexpValidationConfig yValidationConfig = (YRegexpValidationConfig) config
				.getValidationSettings();
		IRegexpValidatorEditpart editpart = null;
		String regexp = yValidationConfig.getRegExpression();
		if (RegexpValidatorEditpart.isValidRegExpression(regexp)) {
			YRegexpValidator yValidator = ValidationFactory.eINSTANCE
					.createYRegexpValidator();
			yValidator.setRegExpression(regexp);
			editpart = getEditpart(config.getContext(), yValidator);
			editpart.setConfig(config);
		}
		return editpart;
	}

	/**
	 * Creates a new beanValidationValidator.
	 *
	 * @param config
	 *            the config
	 * @return the i bean validation validator editpart
	 */
	public static IBeanValidationValidatorEditpart createBeanValidationValidator(
			IValidationConfig config) {
		YBeanValidationValidatorConfig yValidationConfig = (YBeanValidationValidatorConfig) config
				.getValidationSettings();
		IBeanValidationValidatorEditpart editpart = null;
		Class<?> bvalClass = yValidationConfig.getBvalClass();
		String bvalClassName = yValidationConfig
				.getBvalClassFullyQualifiedName();
		if (bvalClass != null || bvalClassName != null) {
			YBeanValidationValidator yValidator = ValidationFactory.eINSTANCE
					.createYBeanValidationValidator();
			yValidator.setBvalClass(bvalClass);
			yValidator.setBvalClassFullyQualifiedName(bvalClassName);
			yValidator.setBvalProperty(yValidationConfig.getBvalProperty());
			editpart = getEditpart(config.getContext(), yValidator);
			editpart.setConfig(config);
		}
		return editpart;
	}

	/**
	 * See {@link ElementEditpart#getEditpart(viewContext, YElement)}.
	 *
	 * @param <A>
	 *            the generic type
	 * @param yValidator
	 *            the y validator
	 * @return the editpart
	 */
	private static <A extends IValidatorEditpart> A getEditpart(IViewContext context,
			YElement yValidator) {
		return ElementEditpart.getEditpart(context, yValidator);
	}

	/**
	 * Internal get validators delta.
	 *
	 * @param config
	 *            the config
	 * @param bridge
	 *            the bridge
	 * @param notification
	 *            the notification
	 * @return the datatype editpart. validator delta
	 */
	public static DatatypeEditpart.ValidatorDelta internalGetValidatorsDelta(
			IValidationConfig config, DatatypeBridge bridge,
			Notification notification) {

		List<IValidatorEditpart> toAdd = new ArrayList<IValidatorEditpart>();
		List<IValidatorEditpart> toRemove = new ArrayList<IValidatorEditpart>();

		List<IValidatorEditpart> activeValidators = bridge
				.getDatatypeValidators();
		if (notification.getFeature() == ValidationPackage.Literals.YMAX_LENGTH_VALIDATION_CONFIG__MAX_LENGTH) {
			int oldValue = notification.getOldIntValue();
			int newValue = notification.getNewIntValue();

			if (oldValue <= 0 && newValue > 0) {
				toAdd.add(createMaxLengthValidator(config));
			} else if (oldValue > 0 && newValue <= 0) {
				toRemove.addAll(findToRemoveValidators(activeValidators,
						YMaxLengthValidator.class));
			} else {
				// nothing to do -> Other changes of attributes are handled by
				// the ValidationConfigToValidatorBridge
			}
		} else if (notification.getFeature() == ValidationPackage.Literals.YMIN_LENGTH_VALIDATION_CONFIG__MIN_LENGTH) {
			int oldValue = notification.getOldIntValue();
			int newValue = notification.getNewIntValue();

			if (oldValue <= 0 && newValue > 0) {
				toAdd.add(createMinLengthValidator(config));
			} else if (oldValue > 0 && newValue <= 0) {
				toRemove.addAll(findToRemoveValidators(activeValidators,
						YMinLengthValidator.class));
			} else {
				// nothing to do -> Other changes of attributes are handled by
				// the ValidationConfigToValidatorBridge
			}
		} else if (notification.getFeature() == ValidationPackage.Literals.YREGEXP_VALIDATION_CONFIG__REG_EXPRESSION) {
			String oldValue = notification.getOldStringValue();
			String newValue = notification.getNewStringValue();

			if (!RegexpValidatorEditpart.isValidRegExpression(oldValue)
					&& RegexpValidatorEditpart.isValidRegExpression(newValue)) {
				toAdd.add(createRegExpressionValidator(config));
			} else if (RegexpValidatorEditpart.isValidRegExpression(oldValue)
					&& !RegexpValidatorEditpart.isValidRegExpression(newValue)) {
				toRemove.addAll(findToRemoveValidators(activeValidators,
						YRegexpValidator.class));
			} else {
				// nothing to do -> Other changes of attributes are handled by
				// the ValidationConfigToValidatorBridge
			}
		} else if (notification.getFeature() == ValidationPackage.Literals.YBEAN_VALIDATION_VALIDATOR_CONFIG__BVAL_CLASS
				|| notification.getFeature() == ValidationPackage.Literals.YBEAN_VALIDATION_VALIDATOR_CONFIG__BVAL_CLASS_FULLY_QUALIFIED_NAME
				|| notification.getFeature() == ValidationPackage.Literals.YBEAN_VALIDATION_VALIDATOR_CONFIG__BVAL_PROPERTY) {
			LOGGER.error("Implement adding and removing BeanValidationValidators!");
		}

		return new DatatypeEditpart.ValidatorDelta(toAdd, toRemove);
	}

	/**
	 * Tries to find all validators of the given type. Each validator of the
	 * same type will then be removed.
	 * <p>
	 * Note: If we need detailed control of the validators to remove (for
	 * instance only validators that have been created by this instance of
	 * datatype editpart), then we have to add a "marker adapter" to the
	 * prepared {@link YValidator}. This marker adapter will keep a reference to
	 * this datatype editpart, and then we can separate validators that have
	 * been added by different editparts. For now, there is no need for it.
	 *
	 * @param activeValidators
	 *            the active validators
	 * @param clazz
	 *            the clazz
	 * @return the list
	 */
	protected static List<IValidatorEditpart> findToRemoveValidators(
			List<IValidatorEditpart> activeValidators,
			Class<? extends YValidator> clazz) {
		List<IValidatorEditpart> toRemove = new ArrayList<IValidatorEditpart>();
		for (IValidatorEditpart editpart : activeValidators) {
			if (clazz.isAssignableFrom(editpart.getModel().getClass())) {
				toRemove.add(editpart);
			}
		}
		return toRemove;
	}

	/**
	 * Collects all validators.
	 *
	 * @param config
	 *            the config
	 * @return the all validators
	 */
	public static DatatypeEditpart.ValidatorDelta getAllValidators(
			IValidationConfig config) {

		List<IValidatorEditpart> toAdd = new ArrayList<IValidatorEditpart>();
		if (!(config.getValidationSettings() instanceof YValidationConfig)) {
			return new DatatypeEditpart.ValidatorDelta(toAdd, null);
		}

		YValidationConfig yValidationConfig = (YValidationConfig) config
				.getValidationSettings();
		if (yValidationConfig instanceof YMinLengthValidationConfig) {
			IMinLengthValidatorEditpart minLength = createMinLengthValidator(config);
			if (minLength != null) {
				toAdd.add(minLength);
			}
		}

		if (yValidationConfig instanceof YMaxLengthValidationConfig) {
			IMaxLengthValidatorEditpart maxLength = createMaxLengthValidator(config);
			if (maxLength != null) {
				toAdd.add(maxLength);
			}
		}

		if (yValidationConfig instanceof YRegexpValidationConfig) {
			IRegexpValidatorEditpart regexp = createRegExpressionValidator(config);
			if (regexp != null) {
				toAdd.add(regexp);
			}
		}

		if (yValidationConfig instanceof YBeanValidationValidatorConfig) {
			IBeanValidationValidatorEditpart beanVal = createBeanValidationValidator(config);
			if (beanVal != null) {
				toAdd.add(beanVal);
			}
		}

		return new DatatypeEditpart.ValidatorDelta(toAdd, null);
	}
}
