/**
 *                                                                            
 *  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:                                                      
 * 	   Florian Pirchner - Initial implementation
 * 
 */
package org.eclipse.osbp.ecview.extension.presentation.vaadin.converter;

import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Collections;
import java.util.Locale;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.IBeanValueProperty;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.extension.model.converter.YQuantityToStringConverter;
import org.eclipse.osbp.runtime.common.types.ITypeProviderService;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchService;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchServiceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.data.Container.Filter;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.filter.Compare;

/**
 * This converter converters values from a "quantity object" (model) to a String
 * (presentation) and back to a quantity object.
 * <p>
 * Therefore it uses following logic:<br>
 * The <code>model value</code> is an object containing the value as a numeric
 * value and the uom (UnitOfMeasure). Value and uom may be nested properties.
 * <h3>Access path</h3>
 * The YQuantityToStringConverter contains three "access path". An "access path"
 * is a property path with dot-notation like "uom.isoCode". To access the values
 * inside the given object, reflection needs to be used.
 * <p>
 * Sample with mappings to the YQuantityToStringConverter:
 * 
 * <pre>
 * /**
 * /**
 * /**
 * }
 * 
 * class Uom {
 * /**
 *    String name;
 *    ...
 * }
 * </pre>
 * 
 * The Quantity bean is the model value. To access the values following
 * accessPath in the YQuantityToStringConverter needs to be used:<br>
 * -> for value: <code>value</code> --> converter#amountPropertyPath<br>
 * -> for uom-Object: <code>uom</code> --> converter#uomPropertyPath<br>
 * -> for uomCode: <code>uom.iso3Code</code> --> converter#uomPropertyPath + "."
 * + converter#uomCodeRelativePropertyPath<br>
 * By reflection the values can become accessed.
 * 
 * <h3>Convert To Presentation</h3> For the convert to presentation
 * implementation, a number format pattern is used. The uom-String-value is
 * added to the number format pattern as a constant. <br>
 * <br>
 * The result may look like: <code>1.200,23 kg</code>
 * 
 * <h3>Convert To Model</h3> For the convert to model implementation, the given
 * presentation-String needs to become parsed. And a new Object of type
 * "model value" needs to be created. The type of the instance, is also
 * contained in the YQuantityToStringConverter object. See
 * {@link YQuantityToStringConverter#getQuantityTypeQualifiedName()}. To get a
 * class based on the FQN use the {@link ITypeProviderService}.<br>
 * The UOM needs to be converted to a valid UOM-object. Therefore use the
 * {@link IBeanSearchService}.
 * 
 * <h3>Unsupported UOMs</h3> To ensure, that only valid UOMs are being entered
 * in the UI, an additional Validator needs to be implemented. It validates,
 * that the entered UOM is valid. To query about valid UOMs, the
 * BeanSearchService is available. See {@link IBeanSearchService}.
 * 
 * <h3>Usage</h3> You may use this converter, to bind a Quantity-Dto to a
 * TextField.
 * 
 */
@SuppressWarnings("serial")
public class QuantityToStringConverter implements Converter<String, Object> {

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

	/** The Constant NUMBER_FORMAT_PATTERN. */
	private static final String NUMBER_FORMAT_PATTERN = "##,##0.00 {$uom}";

	/** The cx converter. */
	private final YQuantityToStringConverter cxConverter;

	/** The bean search service. */
	private IBeanSearchService<Object> beanSearchService;

	/** The quantity type. */
	private final Class<?> quantityType;

	/**
	 * Instantiates a new quantity to string converter.
	 *
	 * @param context
	 *            the context
	 * @param cxConverter
	 *            the cx converter
	 */
	@SuppressWarnings("unchecked")
	public QuantityToStringConverter(IViewContext context,
			YQuantityToStringConverter cxConverter) {
		super();
		this.cxConverter = cxConverter;

		ITypeProviderService typeService = context
				.getService(ITypeProviderService.class.getName());
		quantityType = typeService.forName(null,
				cxConverter.getQuantityTypeQualifiedName());

		// use the BeanProperties to find the UnitOfMeasure by its code
		IBeanValueProperty prop = BeanProperties.value(quantityType,
				cxConverter.getUomPropertyPath());
		IBeanSearchServiceFactory factory = context
				.getService(IBeanSearchServiceFactory.class.getName());
		if (factory != null) {
			beanSearchService = factory.createService((Class<Object>) prop
					.getValueType());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
	 * java.lang.Class, java.util.Locale)
	 */
	@Override
	public Object convertToModel(String valueString,
			Class<? extends Object> targetType, Locale locale)
			throws com.vaadin.data.util.converter.Converter.ConversionException {

		try {
			// parse amount and uom from the given user input
			Number amount = parseAmount(valueString);
			Object uom = parseUom(valueString);

			// set amount and uom to the new quantity object
			Object quantity = quantityType.newInstance();
			applyAmount(quantity, amount);
			applyUom(quantity, uom);

			return quantity;
		} catch (InstantiationException | IllegalAccessException
				| InvocationTargetException | ParseException
				| NoSuchMethodException e) {
			LOGGER.error("{}", e);
			return null;
		}
	}

	/**
	 * Sets the uom into the quantity object.
	 *
	 * @param quantity
	 *            the quantity
	 * @param uom
	 *            the uom
	 * @throws IllegalAccessException
	 *             the illegal access exception
	 * @throws InvocationTargetException
	 *             the invocation target exception
	 * @throws NoSuchMethodException
	 *             the no such method exception
	 */
	private void applyUom(Object quantity, Object uom)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {
		PropertyUtils.setNestedProperty(quantity,
				cxConverter.getUomPropertyPath(), uom);
	}

	/**
	 * Sets the amount into the quantity object.
	 *
	 * @param quantity
	 *            the quantity
	 * @param amount
	 *            the amount
	 * @throws IllegalAccessException
	 *             the illegal access exception
	 * @throws InvocationTargetException
	 *             the invocation target exception
	 * @throws NoSuchMethodException
	 *             the no such method exception
	 */
	private void applyAmount(Object quantity, Number amount)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {
		PropertyUtils.setNestedProperty(quantity,
				cxConverter.getAmountPropertyPath(), amount);
	}

	/**
	 * Parses the amount part from the given value String.<br>
	 * "1200.98 kg" -> "1200.98"
	 *
	 * @param valueString
	 *            the value string
	 * @return the number
	 * @throws ParseException
	 *             the parse exception
	 */
	private Number parseAmount(String valueString) throws ParseException {
		// TODO DOM - enhance with a better split criteria
		String[] tokens = valueString.trim().split(" ");
		String amountString = tokens.length == 2 ? tokens[0] : "";
		return new DecimalFormat().parse(amountString);
	}

	/**
	 * Parses the uom part from the given value String and creates a UOM Object.<br>
	 * "1200.98 kg" -> "kg" -> Object{kg}
	 *
	 * @param valueString
	 *            the value string
	 * @return the object
	 */
	private Object parseUom(String valueString) {
		// TODO DOM - enhance with a better split criteria
		String[] tokens = valueString.trim().split(" ");
		String uomCode = tokens.length == 2 ? tokens[1] : "";
		return getUOMForCode(uomCode);
	}

	/**
	 * Returns the unit of measure for the given uomCode or <code>null</code> if
	 * no uom could be found.
	 *
	 * @param uomCode
	 *            the uom code
	 * @return the UOM for code
	 */
	private Object getUOMForCode(String uomCode) {
		// create a filter based on the relative property path that should be
		// used to show the value
		Filter filter = new Compare.Equal(
				cxConverter.getUomCodeRelativePropertyPath(), uomCode);
		return beanSearchService.getFirstBean(
				Collections.singletonList(filter), null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
	 * .Object, java.lang.Class, java.util.Locale)
	 */
	@Override
	public String convertToPresentation(Object value,
			Class<? extends String> targetType, Locale locale)
			throws com.vaadin.data.util.converter.Converter.ConversionException {

		try {
			String pattern = NUMBER_FORMAT_PATTERN;
			pattern = pattern.replace("{$uom}", getUomCode(value));
			try {
				DecimalFormat format = new DecimalFormat(StringEscapeUtils.unescapeHtml(pattern), new DecimalFormatSymbols(locale));
				return format.format(getAmount(value));
			} catch (IllegalArgumentException e) {
				String msg = String.format(
						"formatter %s is invalid for decimal numbers: %s",
						pattern, e.getLocalizedMessage());
				throw new ConversionException(msg);
			}
		} catch (IllegalAccessException | InvocationTargetException
				| NoSuchMethodException e) {
			LOGGER.error("{}", e);
			return "Error";
		}
	}

	/**
	 * Returns the amount value based on the AmountPropertyPath.
	 *
	 * @param value
	 *            the value
	 * @return the amount
	 * @throws IllegalAccessException
	 *             the illegal access exception
	 * @throws InvocationTargetException
	 *             the invocation target exception
	 * @throws NoSuchMethodException
	 *             the no such method exception
	 */
	private Object getAmount(Object value) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		return PropertyUtils.getNestedProperty(value,
				cxConverter.getAmountPropertyPath());
	}

	/**
	 * Returns the amount value based on the UomPropertyPath.
	 *
	 * @param value
	 *            the value
	 * @return the uom code
	 * @throws IllegalAccessException
	 *             the illegal access exception
	 * @throws InvocationTargetException
	 *             the invocation target exception
	 * @throws NoSuchMethodException
	 *             the no such method exception
	 */
	private String getUomCode(Object value) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		// concat the uomPath and the uomCodePath to directly access the uom
		// code.
		return (String) PropertyUtils.getNestedProperty(
				value,
				cxConverter.getUomPropertyPath() + "."
						+ cxConverter.getUomCodeRelativePropertyPath());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.data.util.converter.Converter#getModelType()
	 */
	@Override
	public Class<Object> getModelType() {
		return Object.class;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.data.util.converter.Converter#getPresentationType()
	 */
	@Override
	public Class<String> getPresentationType() {
		return String.class;
	}

}
