/*******************************************************************************
 * Copyright (c) 2006, 2020 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.team.internal.ui.mapping;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.core.BackgroundEventHandler;
import org.eclipse.team.internal.core.BackgroundEventHandler.Event;
import org.eclipse.team.internal.ui.Policy;
import org.eclipse.team.internal.ui.TeamUIMessages;

/**
 * An abstract class that
 * listens to resource changes and synchronization context changes.
 * <p>
 * This class can be subclassed by clients.
 * <p>
 * <strong>EXPERIMENTAL</strong>. This class or interface has been added as
 * part of a work in progress. There is a guarantee neither that this API will
 * work nor that it will remain the same. Please do not use this API without
 * consulting with the Platform/Team team.
 * </p>
 * @since 3.3
 */
public abstract class CompareInputChangeNotifier implements
		IResourceChangeListener {

	private Map<ICompareInput, CompareInputConnecton> inputs = new HashMap<>();
	private InputChangeEventHandler eventHandler;

	private class CompareInputConnecton {
		private int connections;
		public void increment() {
			connections++;
		}
		public void decrement() {
			if (connections > 0)
				connections--;

		}
		public boolean isDisconnected() {
			return connections == 0;
		}
	}

	private static final int COMPARE_INPUT_CHANGE = 1;

	private static class InputChangeEvent extends Event {
		private final ICompareInput[] inputs;
		public InputChangeEvent(ICompareInput[] inputs) {
			super(COMPARE_INPUT_CHANGE);
			this.inputs = inputs;

		}
		public ICompareInput[] getChangedInputs() {
			return inputs;
		}
	}

	private class InputChangeEventHandler extends BackgroundEventHandler {

		private final Set<ICompareInput> changedInputs = new HashSet<>();
		private final List<Event> pendingRunnables = new ArrayList<>();

		protected InputChangeEventHandler() {
			super(TeamUIMessages.CompareInputChangeNotifier_0, TeamUIMessages.CompareInputChangeNotifier_1);
		}

		@Override
		protected boolean doDispatchEvents(IProgressMonitor monitor)
				throws TeamException {
			ICompareInput[] toDispatch;
			RunnableEvent[] events;
			synchronized (pendingRunnables) {
				synchronized (changedInputs) {
					if (changedInputs.isEmpty() && pendingRunnables.isEmpty())
						return false;
					toDispatch = changedInputs.toArray(new ICompareInput[changedInputs.size()]);
					events = pendingRunnables.toArray(new RunnableEvent[pendingRunnables.size()]);
					changedInputs.clear();
					pendingRunnables.clear();
				}
			}
			dispatchChanges(toDispatch, monitor);
			for (RunnableEvent event : events) {
				executeRunnableNow(event, monitor);
			}
			return true;
		}

		@Override
		protected void processEvent(Event event, IProgressMonitor monitor)
				throws CoreException {
			int type = event.getType();
			switch (type) {
				case BackgroundEventHandler.RUNNABLE_EVENT :
					RunnableEvent runnableEvent = ((RunnableEvent)event);
					if (runnableEvent.isPreemtive())
						executeRunnableNow(event, monitor);
					else
						executeRunnableDuringDispatch(event);
					break;
				case COMPARE_INPUT_CHANGE :
					if (event instanceof InputChangeEvent) {
						InputChangeEvent changeEvent = (InputChangeEvent) event;
						ICompareInput[] inputs = changeEvent.getChangedInputs();
						synchronized (changedInputs) {
							Collections.addAll(changedInputs, inputs);
						}
					}
					break;
			}
		}

		private void executeRunnableDuringDispatch(Event event) {
			synchronized (pendingRunnables) {
				pendingRunnables.add(event);
			}
		}

		private void executeRunnableNow(Event event, IProgressMonitor monitor) {
			try {
				// Dispatch any queued results to clear pending output events
				dispatchEvents(Policy.subMonitorFor(monitor, 1));
			} catch (TeamException e) {
				handleException(e);
			}
			try {
				((RunnableEvent)event).run(Policy.subMonitorFor(monitor, 1));
			} catch (CoreException e) {
				handleException(e);
			}
		}

		protected synchronized void queueEvent(Event event) {
			super.queueEvent(event, false);
		}

		@Override
		protected long getShortDispatchDelay() {
			// Only wait 250 for additional changes to come in
			return 250;
		}

		@Override
		protected boolean belongsTo(Object family) {
			return CompareInputChangeNotifier.this.belongsTo(family);
		}
	}

	/**
	 * Create a change notifier for the given synchronization context.
	 */
	public CompareInputChangeNotifier() {
		super();
	}

	/**
	 * Initialize the change notifier. This method is called from the
	 * constructor and registers a listener with the workspace and the
	 * synchronization context. It also registers a listener with the context
	 * cache which will unregister the listeners when the context is disposed.
	 * Subclasses may extend this method.
	 */
	public void initialize() {
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
		eventHandler = new InputChangeEventHandler();
	}

	/**
	 * Dispose of the change notifier. This method is invoked when the context
	 * to which the change notifier is associated is disposed.
	 * Subclasses may extend this method.
	 */
	public void dispose() {
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
		if (eventHandler != null)
			eventHandler.shutdown();
	}

	/**
	 * Connect the input to this change notifier. Once connected, the change notifier will issue
	 * change events for the given input. When change notification is no longer desired, the
	 * input should be disconnected. The number of calls to {@link #connect(ICompareInput)} needs to
	 * be matched by the same number of calls to {@link #disconnect(ICompareInput)}.
	 * @param input the compare input
	 */
	public void connect(ICompareInput input) {
		CompareInputConnecton con = inputs.get(input);
		if (con == null) {
			con = new CompareInputConnecton();
			inputs.put(input, con);
		}
		con.increment();
	}

	/**
	 * Disconnect the input from this change notifier.
	 * @param input the compare input
	 * @see #connect(ICompareInput)
	 */
	public void disconnect(ICompareInput input) {
		CompareInputConnecton con = inputs.get(input);
		if (con != null) {
			con.decrement();
			if (con.isDisconnected()) {
				inputs.remove(input);
			}
		}
	}

	/**
	 * Return the array of inputs that have connections.
	 * @return the array of inputs that have connections
	 */
	protected ICompareInput[] getConnectedInputs() {
		return inputs.keySet().toArray(new ICompareInput[inputs.size()]);
	}

	/**
	 * Send out notification that the given compare inputs have changed.
	 * @param inputs the changed inputs
	 */
	protected void inputsChanged(ICompareInput[] inputs) {
		InputChangeEvent event = new InputChangeEvent(inputs);
		eventHandler.queueEvent(event);
	}

	/**
	 * Dispatch the changes to the given inputs.
	 * @param inputs the changed compare inputs
	 * @param monitor a progress monitor
	 */
	protected void dispatchChanges(final ICompareInput[] inputs, IProgressMonitor monitor) {
		prepareInputs(inputs, monitor);
		Display.getDefault().syncExec(() -> fireChanges(inputs));
	}

	/**
	 * Prepare the inputs in the background before firing the compare input change event.
	 * This allows for the caching of contents etc. before the input change event is fired.
	 * @param inputs the changed inputs
	 * @param monitor a progress monitor
	 */
	protected void prepareInputs(ICompareInput[] inputs, IProgressMonitor monitor) {
		monitor.beginTask(null, inputs.length * 100);
		for (ICompareInput input : inputs) {
			prepareInput(input, Policy.subMonitorFor(monitor, 100));
		}
		monitor.done();
	}

	/**
	 * Prepare the input before firing the compare input change event.
	 * This allows for the caching of contents etc. before the input change event is fired.
	 * This method is called from {@link #prepareInputs(ICompareInput[], IProgressMonitor)}
	 * for each input. By default, nothing is done, subclasses may override.
	 * @param input the compare input
	 * @param monitor a progress monitor
	 */
	protected void prepareInput(ICompareInput input, IProgressMonitor monitor) {
		// Default is to do nothing
	}

	/**
	 * Update the compare inputs and fire the change events.
	 * This method is called from the UI thread after the inputs have
	 * been prepared in a background thread
	 * (see {@link #prepareInputs(ICompareInput[], IProgressMonitor)})
	 * @param inputs the changed inputs
	 */
	protected void fireChanges(ICompareInput[] inputs) {
		for (ICompareInput input : inputs) {
			fireChange(input);
		}
	}

	/**
	 * Run the given runnable in the background.
	 * @param runnable the runnable
	 */
	protected void runInBackground(IWorkspaceRunnable runnable) {
		eventHandler.queueEvent(new BackgroundEventHandler.RunnableEvent(runnable, false));
	}

	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		List<ICompareInput> changedInputs = new ArrayList<>();
		ICompareInput[] inputs = getConnectedInputs();
		for (ICompareInput input : inputs) {
			IResource[] resources = getResources(input);
			for (IResource resource : resources) {
				if (resource != null) {
					IResourceDelta delta = event.getDelta().findMember(resource.getFullPath());
					if (delta != null) {
						if ((delta.getKind() & (IResourceDelta.ADDED | IResourceDelta.REMOVED)) > 0
								|| (delta.getKind() & (IResourceDelta.CHANGED)) > 0
								&& (delta.getFlags() & (IResourceDelta.CONTENT | IResourceDelta.REPLACED)) > 0) {
							changedInputs.add(input);
							break;
						}
					}
				}
			}
		}
		if (!changedInputs.isEmpty())
			handleInputChanges(changedInputs.toArray(new ICompareInput[changedInputs.size()]), true);
	}

	/**
	 * Return the resources covered by the given compare input.
	 * This method is used by the {@link #resourceChanged(IResourceChangeEvent)}
	 * method to determine if a workspace change affects the compare input.
	 * @param input the compare input
	 * @return the resources covered by the given compare input
	 */
	protected abstract IResource[] getResources(ICompareInput input);

	/**
	 * Handle the input changes by notifying any listeners of the changed inputs.
	 * @param inputs the changed inputs
	 */
	protected void handleInputChanges(ICompareInput[] inputs, boolean force) {
		ICompareInput[] realChanges;
		if (force) {
			realChanges = inputs;
		} else {
			List<ICompareInput> result = new ArrayList<>();
			for (ICompareInput input : inputs) {
				if (isChanged(input)) {
					result.add(input);
				}
			}
			realChanges = result.toArray(new ICompareInput[result.size()]);
		}
		if (realChanges.length > 0)
			inputsChanged(realChanges);
	}

	/**
	 * Return whether the given compare input has changed and requires
	 * a compare input change event to be fired.
	 * @param input the compare input
	 * @return whether the given compare input has changed
	 */
	protected boolean isChanged(ICompareInput input) {
		if (input instanceof AbstractCompareInput) {
			AbstractCompareInput ci = (AbstractCompareInput) input;
			return ci.needsUpdate();
		}
		return false;
	}

	/**
	 * Update the compare input and fire the change event.
	 * This method is called from {@link #fireChanges(ICompareInput[])}
	 * for each changed input.
	 * @param input the changed compare input
	 */
	protected void fireChange(ICompareInput input) {
		if (input instanceof AbstractCompareInput) {
			AbstractCompareInput ci = (AbstractCompareInput) input;
			ci.update();
		}
	}

	/**
	 * Return whether the background handler for this notifier belongs to the
	 * given job family.
	 * @param family the job family
	 * @return whether the background handler belongs to the given job family.
	 * @see Job#belongsTo(Object)
	 */
	protected boolean belongsTo(Object family) {
		return false;
	}

}
