/*******************************************************************************
 * Copyright (c) 2006, 2015 IBM Corporation and others.
 *
 * 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:
 *     IBM Corporation - initial API and implementation
 ******************************************************************************/

package org.eclipse.ui.internal.contexts;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.commands.contexts.Context;
import org.eclipse.core.commands.contexts.IContextManagerListener;
import org.eclipse.core.expressions.AndExpression;
import org.eclipse.core.expressions.Expression;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISourceProvider;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;

/**
 * A context service which delegates almost all responsibility to the parent
 * service.
 * <p>
 * This class is not intended for use outside of the
 * <code>org.eclipse.ui.workbench</code> plug-in.
 * </p>
 *
 * @since 3.2
 *
 */
public class SlaveContextService implements IContextService {

	/**
	 * The parent context service, which is never <code>null</code>.
	 */
	protected IContextService fParentService;

	/**
	 * The default expression used when {@link #activateContext(String) } is called.
	 * Contexts contributed that use this expression will only be active with this
	 * service is active.
	 */
	protected Expression fDefaultExpression;

	/**
	 * Our contexts that are currently active with the parent context service.
	 */
	protected Set<IContextActivation> fParentActivations;

	/**
	 * A map of the local activation to the parent activations. If this service is
	 * inactive, then all parent activations are <code>null</code>. Otherwise, they
	 * point to the corresponding activation in the parent service.
	 */
	protected Map<IContextActivation, IContextActivation> fLocalActivations;

	/**
	 * A collection of context manager listeners. The listeners are not
	 * activated/deactivated, but they will be removed when this service is
	 * disposed.
	 */
	private Collection<IContextManagerListener> fContextManagerListeners;

	/**
	 * A collection of source providers. The listeners are not
	 * activated/deactivated, but they will be removed when this service is
	 * disposed.
	 */
	private Collection<ISourceProvider> fSourceProviders;

	/**
	 * A collection of shells registered through this service. The listeners are not
	 * activated/deactivated, but they will be removed when this service is
	 * disposed.
	 */
	private Collection<Shell> fRegisteredShells;

	/**
	 * Construct the new slave.
	 *
	 * @param parentService     the parent context service; must not be
	 *                          <code>null</code>.
	 * @param defaultExpression A default expression to use to determine viability.
	 *                          It's mainly used for conflict resolution. It can be
	 *                          <code>null</code>.
	 */
	public SlaveContextService(IContextService parentService, Expression defaultExpression) {
		if (parentService == null) {
			throw new NullPointerException("The parent context service must not be null"); //$NON-NLS-1$
		}
		fParentService = parentService;
		fDefaultExpression = defaultExpression;
		fParentActivations = new HashSet<>();
		fLocalActivations = new HashMap<>();
		fContextManagerListeners = new ArrayList<>();
		fSourceProviders = new ArrayList<>();
		fRegisteredShells = new ArrayList<>();
	}

	@Override
	public void deferUpdates(boolean defer) {
		fParentService.deferUpdates(defer);
	}

	@Override
	public IContextActivation activateContext(String contextId) {

		ContextActivation activation = new ContextActivation(contextId, fDefaultExpression, this);
		return doActivateContext(activation);
	}

	@Override
	public IContextActivation activateContext(String contextId, Expression expression) {
		return activateContext(contextId, expression, false);
	}

	@Override
	public IContextActivation activateContext(String contextId, Expression expression, boolean global) {
		if (global) {
			IContextActivation activation = fParentService.activateContext(contextId, expression, global);
			fParentActivations.add(activation);
			return activation;
		}

		Expression aExpression = fDefaultExpression;
		if (expression != null && fDefaultExpression != null) {
			final AndExpression andExpression = new AndExpression();
			andExpression.add(expression);
			andExpression.add(fDefaultExpression);
			aExpression = andExpression;
		} else if (expression != null) {
			aExpression = expression;
		}

		ContextActivation activation = new ContextActivation(contextId, aExpression, this);
		return doActivateContext(activation);
	}

	@Override
	public IContextActivation activateContext(String contextId, Expression expression, int sourcePriorities) {
		return activateContext(contextId, expression);
	}

	@Override
	public void addContextManagerListener(IContextManagerListener listener) {
		if (!fContextManagerListeners.contains(listener)) {
			fContextManagerListeners.add(listener);
		}
		fParentService.addContextManagerListener(listener);
	}

	@Override
	public void addSourceProvider(ISourceProvider provider) {
		if (!fSourceProviders.contains(provider)) {
			fSourceProviders.add(provider);
		}
		fParentService.addSourceProvider(provider);
	}

	@Override
	public void deactivateContext(IContextActivation activation) {
		IContextActivation parentActivation = null;
		if (fLocalActivations.containsKey(activation)) {
			parentActivation = fLocalActivations.remove(activation);
		} else {
			parentActivation = activation;
		}
		if (parentActivation != null) {
			fParentService.deactivateContext(parentActivation);
			fParentActivations.remove(parentActivation);
		}
	}

	@Override
	public void deactivateContexts(Collection activations) {
		Object[] array = activations.toArray();
		for (int i = 0; i < array.length; i++) {
			deactivateContext((IContextActivation) array[i]);
			array[i] = null;
		}
	}

	@Override
	public void dispose() {
		fParentService.deactivateContexts(fParentActivations);
		fParentActivations.clear();
		fLocalActivations.clear();

		// Remove any "resource", like listeners, that were associated
		// with this service.
		if (!fContextManagerListeners.isEmpty()) {
			for (IContextManagerListener element : fContextManagerListeners.toArray(new IContextManagerListener[0])) {
				removeContextManagerListener(element);
			}
			fContextManagerListeners.clear();
		}
		if (!fSourceProviders.isEmpty()) {
			for (Object element : fSourceProviders.toArray()) {
				removeSourceProvider((ISourceProvider) element);
			}
			fSourceProviders.clear();
		}
		if (!fRegisteredShells.isEmpty()) {
			for (Object element : fRegisteredShells.toArray()) {
				unregisterShell((Shell) element);
			}
			fRegisteredShells.clear();
		}
	}

	/**
	 * Activate the context with respect to this slave service.
	 *
	 * @param contextId  the context id
	 * @param expression the expression to use
	 * @return the activated context
	 */
	protected IContextActivation doActivateContext(IContextActivation activation) {
		IContextActivation parentActivation = fParentService.activateContext(activation.getContextId(),
				activation.getExpression());
		fParentActivations.add(parentActivation);
		fLocalActivations.put(activation, parentActivation);
		return activation;
	}

	@Override
	public Collection getActiveContextIds() {
		return fParentService.getActiveContextIds();
	}

	@Override
	public Context getContext(String contextId) {
		return fParentService.getContext(contextId);
	}

	@Override
	public Collection getDefinedContextIds() {
		return fParentService.getDefinedContextIds();
	}

	@Override
	public Context[] getDefinedContexts() {
		return fParentService.getDefinedContexts();
	}

	@Override
	public int getShellType(Shell shell) {
		return fParentService.getShellType(shell);
	}

	@Override
	public void readRegistry() {
		fParentService.readRegistry();
	}

	@Override
	public boolean registerShell(Shell shell, int type) {
		if (!fRegisteredShells.contains(shell)) {
			fRegisteredShells.add(shell);
		}
		return fParentService.registerShell(shell, type);
	}

	@Override
	public void removeContextManagerListener(IContextManagerListener listener) {
		fContextManagerListeners.remove(listener);
		fParentService.removeContextManagerListener(listener);
	}

	@Override
	public void removeSourceProvider(ISourceProvider provider) {
		fSourceProviders.remove(provider);
		fParentService.removeSourceProvider(provider);
	}

	@Override
	public boolean unregisterShell(Shell shell) {
		fRegisteredShells.remove(shell);
		return fParentService.unregisterShell(shell);
	}
}
