/**
 *                                                                            
 * 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 v1.0       
 * which accompanies this distribution, and is available at                  
 * http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.infogrid.ecview;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.osbp.ecview.core.common.context.ContextException;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlot;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.extension.model.extension.util.SimpleExtensionModelFactory;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.ecview.extension.grid.CxGrid;
import org.eclipse.osbp.ecview.extension.grid.CxGridPackage;
import org.eclipse.osbp.ecview.extension.grid.editparts.IGridEditpart;
import org.eclipse.osbp.ecview.extension.grid.util.CxGridUtil;
import org.eclipse.osbp.infogrid.api.AbstractGridSourceDescriptor;
import org.eclipse.osbp.infogrid.api.IECViewGridFactory;
import org.eclipse.osbp.infogrid.api.IECViewGridSourceDescriptor;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSource;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSourceEQFilter;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSourceInput;
import org.eclipse.osbp.runtime.common.i18n.II18nService;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.VaadinRenderer;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.ui.api.useraccess.IUserAccessService;
import org.eclipse.osbp.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.ui.CssLayout;

/**
 * You need to pass the following properties during the creation of the
 * descriptor.
 * <p>
 * <h2>services</h2>
 * II18nService<br>
 * E4EventBrokerAdapter<br>
 * <h2>properties</h2>
 * locale<br>
 * 
 * <h2>Sample</h2>
 * 
 * <pre>
 * // render the Vaadin UI
 * Map&lt;String, Object&gt; properties = new HashMap&lt;String, Object&gt;();
 * 
 * // register services to be used
 * Map&lt;String, Object&gt; services = new HashMap&lt;String, Object&gt;();
 * services.put(
 * 		org.eclipse.osbp.runtime.common.event.IEventBroker.class.getName(),
 * 		new E4EventBrokerAdapter(e4EventBroker));
 * services.put(II18nService.class.getName(), i18nService);
 * properties.put(IViewContext.PARAM_SERVICES, services);
 */
public class ECViewGridSourceDescriptor extends AbstractGridSourceDescriptor
		implements IECViewGridSourceDescriptor {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(ECViewGridSourceDescriptor.class);

	private static final String PROP_LOCALE = "locale";
	private static final String BEAN_SLOT = "input";

	private IECViewGridFactory factory;
	private IViewContext viewContext;

	private Locale locale;

	private CxGrid cxGrid;

	private SavedAdapter savedAdapter;

	private EditorSavedStrategy editorSavedStrategy;

	public ECViewGridSourceDescriptor(Class<?> inputType, CxGridSource source,
			IECViewGridFactory factory) {
		super(inputType, source);
		this.factory = factory;
	}

	@Override
	public Object getComponent() {
		checkDisposed();

		if (viewContext == null) {
			try {
				renderView();
			} catch (ContextException e) {
				throw new IllegalStateException(e);
			}
		}
		return viewContext.getRootLayout();
	}

	protected void renderView() throws ContextException {

		cxGrid = factory.createGrid(getInputType(), getSource());
		SimpleExtensionModelFactory yFactory = new SimpleExtensionModelFactory();

		YView yView = yFactory.createView();
		YBeanSlot yBeanSlot = yFactory.createBeanSlot();
		yBeanSlot.setName(BEAN_SLOT);
		yBeanSlot.setValueType(Object.class);
		yView.getBeanSlots().add(yBeanSlot);
		yView.setContent(cxGrid);

		IUserAccessService userAccessService;

		// First alternative to get IUserAccessService via descriptor properties
		@SuppressWarnings("unchecked")
		Map<String, Object> services = (Map<String, Object>) properties
				.get(IViewContext.PARAM_SERVICES);
		if (services.containsKey(IUser.class.getName())) {
			User user = (User) services.get(IUser.class.getName());
			if (user != null) {
				userAccessService = user.getUserAccessService();
				cxGrid = CxGridUtil.setPermissions(userAccessService, cxGrid);
			}
		}
		// Second alternative to get IUserAccessService via bundle context
		// BundleContext bc = FrameworkUtil.getBundle(getClass())
		// .getBundleContext();
		// ServiceReference<IUserAccessService> ref = bc
		// .getServiceReference(IUserAccessService.class);
		// if (ref != null) {
		// userAccessService = bc.getService(ref);
		// cxGrid = CxGridUtil.setPermissions(userAccessService, cxGrid);
		// }

		CssLayout rootLayout = new CssLayout();
		rootLayout.setSizeFull();
		VaadinRenderer renderer = new VaadinRenderer();
		viewContext = renderer.render(rootLayout, yView, properties);
		viewContext.setLocale(locale);

		updateSavedStrategy();
	}

	@Override
	public void setInput(Object value) {
		checkDisposed();

		if (viewContext != null) {
			viewContext.setBean(BEAN_SLOT, value);
			IGridEditpart editpart = ModelUtil.findEditpart(cxGrid);
			if (editpart != null) {
				Map<String, Object> filterProps = createFilterMap(value);
				editpart.setFilter(filterProps);
			}
		}
	}

	/**
	 * Creates a map containing the property as key and the filterValue as
	 * value.<br>
	 * These values will be added to the Grid as filter statements.
	 * 
	 * @param value
	 * @return
	 */
	protected Map<String, Object> createFilterMap(Object value) {
		Map<String, Object> filterProps = new HashMap<>();
		if (value == null) {
			return filterProps;
		}
		CxGridSourceInput input = findGridSourceInput(getSource());
		if (input != null) {
			for (CxGridSourceEQFilter filter : input.getFilters()) {
				// the target property from the grids content.
				String targetFilterProp = filter.getRootTypePropertyPath()
						.getDotPath();
				// the source property where the filter value should be used
				// from
				String sourceFilterProp = filter.getInputTypePropertyPath()
						.getDotPath();
				try {
					Object sourceFilterValue = PropertyUtils.getNestedProperty(
							value, sourceFilterProp);
					filterProps.put(targetFilterProp, sourceFilterValue);
				} catch (IllegalAccessException | InvocationTargetException
						| NoSuchMethodException e) {
					LOGGER.error("{}", e);
				}
			}
		}
		return filterProps;
	}

	private CxGridSourceInput findGridSourceInput(CxGridSource source) {
		for (CxGridSourceInput input : source.getInputs()) {
			if (getInputType().getName().equals(input.getInputTypeFQN())) {
				return input;
			}
		}
		return null;
	}

	@Override
	public void setLocale(Locale locale) {
		this.locale = locale;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void setProperties(Map<String, Object> properties) {
		super.setProperties(properties);

		if (properties == null) {
			LOGGER.warn("You should pass properties to ensure proper functionality!");
			return;
		}

		if (!properties.containsKey(PROP_LOCALE)) {
			LOGGER.warn("You should pass the locale.");
		} else {
			this.locale = (Locale) properties.get(PROP_LOCALE);
		}

		if (properties.containsKey(PROP_MANUAL_BEANS)) {
			boolean useManualBeans = (boolean) properties
					.get(PROP_MANUAL_BEANS);
			if (useManualBeans) {
				source.getTags().add(PROP_MANUAL_BEANS);
			}
		} else {
			source.getTags().remove(PROP_MANUAL_BEANS);
		}

		if (!properties.containsKey(IViewContext.PARAM_SERVICES)) {
			LOGGER.warn("You should pass some services. See JavaDoc of this class.");
		} else {
			Map<String, Object> services = (Map<String, Object>) properties
					.get(IViewContext.PARAM_SERVICES);
			if (!services.containsKey(II18nService.ID)) {
				LOGGER.warn("You should pass the I18nService.");
			}
			if (!services
					.containsKey("org.eclipse.osbp.runtime.common.event.IEventBroker")) {
				LOGGER.warn("You should pass the org.eclipse.osbp.runtime.common.event.IEventBroker as an E4EventBrokerAdapter.");
			}
		}
	}

	@Override
	protected void internalDispose() {

		if (savedAdapter != null) {
			cxGrid.eAdapters().remove(savedAdapter);
			savedAdapter = null;
		}

		if (viewContext != null) {
			viewContext.dispose();
			viewContext = null;
		}

		if (properties != null) {
			properties.clear();
			properties = null;
		}

		factory = null;
	}

	@Override
	public void setEditorSavedStrategy(EditorSavedStrategy strategy) {
		this.editorSavedStrategy = strategy;
		updateSavedStrategy();
	}

	protected void updateSavedStrategy() {
		if (cxGrid == null) {
			return;
		}
		if (editorSavedStrategy != null) {
			if (savedAdapter == null) {
				savedAdapter = new SavedAdapter();
			}
			if (!cxGrid.eAdapters().contains(savedAdapter)) {
				cxGrid.eAdapters().add(savedAdapter);
			}
		} else {
			if (savedAdapter != null) {
				cxGrid.eAdapters().remove(savedAdapter);
			}
		}
	}

	@Override
	public CxGrid getGrid() {
		return cxGrid;
	}

	private class SavedAdapter extends AdapterImpl {
		@Override
		public void notifyChanged(Notification msg) {
			if (msg.getFeature() == CxGridPackage.Literals.CX_GRID__EDITOR_SAVED) {
				if (editorSavedStrategy != null) {
					editorSavedStrategy.editorSaved(msg.getNewValue());
				}
			}
		}
	}
}
