/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - 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 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
package org.eclipse.osbp.runtime.jsr303.validation.common;

import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.MessageInterpolator;
import javax.validation.MessageInterpolator.Context;
import javax.validation.Payload;
import javax.validation.metadata.ConstraintDescriptor;

import org.eclipse.osbp.runtime.common.validation.ErrorSeverity;
import org.eclipse.osbp.runtime.common.validation.IStatus;
import org.eclipse.osbp.runtime.common.validation.InfoSeverity;
import org.eclipse.osbp.runtime.common.validation.Status;
import org.eclipse.osbp.runtime.common.validation.WarningSeverity;
import org.eclipse.osbp.runtime.jsr303.validation.OSGiMessageInterpolator;

public class ValidationUtil {

	private ValidationUtil() {
		super();
	}

	public static MessageInterpolator createNewMessageInterpolator(Locale locale) {
		OSGiMessageInterpolator interpolator = new OSGiMessageInterpolator();
		interpolator.setLocale(locale);
		return interpolator;
	}

	public static void updateLocale(MessageInterpolator interpolator, Locale locale) {
		if (interpolator instanceof OSGiMessageInterpolator) {
			((OSGiMessageInterpolator) interpolator).setLocale(locale);
		}
	}

	/**
	 * Maps the contraint violations to IStatus.
	 * 
	 * @param originalViolations
	 * @return
	 */
	public static Set<IStatus> getStatus(Class<?> creator,
			@SuppressWarnings("rawtypes") Set<ConstraintViolation> originalViolations) {

		Set<IStatus> result = new HashSet<IStatus>();
		for (ConstraintViolation<?> violation : originalViolations) {

			IStatus.Severity severity = getSeverity(violation);
			String code = getMessageCode(violation);

			Class<?> clazz = violation.getLeafBean() != null ? violation.getLeafBean().getClass() : null;
			IStatus status = Status.createStatus(code, clazz, severity, violation.getMessage());
			status.putProperty(IStatus.PROP_JAVAX_CONSTRAINT, violation);
			status.putProperty(IStatus.PROP_JAVAX_PROPERTY_PATH, violation.getPropertyPath().toString());
			status.putProperty(IStatus.PROP_JAVAX_LEAF_BEAN, violation.getLeafBean());

			if (creator != null) {
				status.putProperty(IStatus.PROP_CREATOR, creator.getName());
			}

			result.add(status);
		}

		return result;
	}

	protected static String getMessageCode(ConstraintViolation<?> violation) {
		String message = violation.getMessageTemplate().substring(1, violation.getMessageTemplate().length() - 1);
		if (message.contains(":")) {
			String[] tokens = message.split(":");
			return tokens[1];
		}

		return violation.getPropertyPath().toString();
	}

	protected static IStatus.Severity getSeverity(ConstraintViolation<?> violation) {
		IStatus.Severity severity = IStatus.Severity.ERROR;
		Set<Class<? extends Payload>> payloads = violation.getConstraintDescriptor().getPayload();
		if (payloads.size() > 0) {
			Class<? extends Payload> payload = payloads.iterator().next();
			if (payload == InfoSeverity.class) {
				severity = IStatus.Severity.INFO;
			} else if (payload == WarningSeverity.class) {
				severity = IStatus.Severity.WARNING;
			} else if (payload == ErrorSeverity.class) {
				severity = IStatus.Severity.ERROR;
			}
		}
		return severity;
	}

	public static String replaceMessageParameter(String message, Context context) {
		ConstraintDescriptor<?> desc = context.getConstraintDescriptor();
		Map<String, Object> props = desc.getAttributes();

		for (Map.Entry<String, Object> entry : props.entrySet()) {
			String replacement = "\\{" + entry.getKey() + "\\}";
			message = message.replaceAll(replacement, entry.getValue().toString());
		}

		return message;
	}

	public static String extractMessage(String message) {
		if (message.startsWith("{")) {
			message = message.substring(1, message.length() - 1);
		}
		if (message.contains(":")) {
			String[] i18nKey = message.split(":");
			message = i18nKey[0];
		}
		return message;
	}

}
