/**
 * 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 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.grid.editparts;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.eclipse.osbp.ecview.extension.grid.editparts.presentation.IGridCellStyleGeneratorFactory;

/**
 * Delegates the calls to the implementing services provided by OSGi-DS.
 */
public final class DelegatingGridCellStyleGeneratorFactory implements
		IGridCellStyleGeneratorFactory {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(DelegatingGridCellStyleGeneratorFactory.class);
	private static DelegatingGridCellStyleGeneratorFactory instance = new DelegatingGridCellStyleGeneratorFactory();

	private final List<IGridCellStyleGeneratorFactory> delegates = Collections
			.synchronizedList(new ArrayList<IGridCellStyleGeneratorFactory>());
	private List<IGridCellStyleGeneratorFactory> stashed;

	private DelegatingGridCellStyleGeneratorFactory() {
	}

	/**
	 * Returns the instance of that manager.
	 * 
	 * @return the instance
	 */
	public static DelegatingGridCellStyleGeneratorFactory getInstance() {
		return instance;
	}

	/**
	 * Removes all factories. Should only be used very carefully
	 */
	public void clear() {
		delegates.clear();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isFor(IViewContext uiContext,
			IGridCellStyleGeneratorEditpart editpart) {
		for (IGridCellStyleGeneratorFactory factory : delegates
				.toArray(new IGridCellStyleGeneratorFactory[delegates.size()])) {
			if (factory.isFor(uiContext, editpart)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public Object createCellStyleGenerator(IViewContext uiContext,
			IGridCellStyleGeneratorEditpart editpart)
			throws IllegalArgumentException {
		for (IGridCellStyleGeneratorFactory factory : delegates
				.toArray(new IGridCellStyleGeneratorFactory[delegates.size()])) {
			if (factory.isFor(uiContext, editpart)) {
				try {
					Object result = factory
							.createCellStyleGenerator(uiContext, editpart);
					if (result != null) {
						return result;
					}
				} catch (IllegalArgumentException e) {
					// nothing to do. Try the next factory
				}
			}
		}
		LOGGER.error("No proper converterFactory found for elements {} {}",
				new Object[] { uiContext, editpart });
		return null;
	}

	/**
	 * Will stash the current state. ONLY FOR TESTS!
	 */
	public void stash() {
		if (stashed != null) {
			return;
		}
		stashed = new ArrayList<IGridCellStyleGeneratorFactory>(delegates);
	}

	/**
	 * Will unstash the stashed state. ONLY FOR TESTS!
	 */
	public void unstash() {
		if (stashed == null) {
			return;
		}
		delegates.clear();
		delegates.addAll(stashed);
		stashed = null;
	}

	/**
	 * Adds a new factory to the manager.
	 * 
	 * @param factory
	 *            Factory to be added.
	 */
	public void addDelegate(IGridCellStyleGeneratorFactory factory) {
		if (!delegates.contains(factory)) {
			delegates.add(factory);
		}
	}

	/**
	 * Removes the factory from the manager.
	 * 
	 * @param factory
	 *            Factory to be removed.
	 */
	public void removeDelegate(IGridCellStyleGeneratorFactory factory) {
		if (factory == null) {
			return;
		}
		delegates.remove(factory);
	}

	/**
	 * OSGi-DS component.
	 */
	@Component(immediate=true, service={})
	public static class ServiceComponent {

		/**
		 * Called by OSGi-DS.
		 * 
		 * @param context
		 *            Component context
		 * @param properties
		 *            Map of properties
		 */
		@Activate
		public void activate(ComponentContext context,
				Map<String, Object> properties) {
			LOGGER.debug("DelegatingPresenterFactory activated");
		}

		/**
		 * Called by OSGi-DS.
		 * 
		 * @param context
		 *            Component context
		 * @param properties
		 *            Map of properties
		 */
		@Deactivate
		public void deactivate(ComponentContext context,
				Map<String, Object> properties) {
			LOGGER.debug("DelegatingPresenterFactory deactivated");
		}

		/**
		 * Called by OSGi DS.
		 * 
		 * @param factory
		 *            Factory to be added
		 */
		@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, unbind = "removeDelegate")
		protected void addDelegate(IGridCellStyleGeneratorFactory factory) {
			DelegatingGridCellStyleGeneratorFactory.getInstance().addDelegate(
					factory);
		}

		/**
		 * Called by OSGi DS.
		 * 
		 * @param factory
		 *            Factory to be added
		 */
		protected void removeDelegate(IGridCellStyleGeneratorFactory factory) {
			DelegatingGridCellStyleGeneratorFactory.getInstance()
					.removeDelegate(factory);
		}
	}
}
