/*=============================================================================#
 # Copyright (c) 2008, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImIdentityList;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
import org.eclipse.statet.ltk.model.core.IModelElementDelta;
import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;


/**
 * Controller implementation combining {@link IPostSelectionProvider} and 
 * {@link IModelElementInputProvider} to provide support for
 * {@link ISelectionWithElementInfoListener}.
 */
public class PostSelectionWithElementInfoController {
	
	
	private class SelectionTask extends Job {
		
		
		private final class Data extends LTKInputData {
			
			int stateNr;
			
			Data(final ISourceUnit input, final SelectionChangedEvent currentSelection, final int runNr) {
				super(input, (currentSelection != null) ? currentSelection.getSelection() : null);
				this.stateNr= runNr;
			}
			
			@Override
			public boolean isStillValid() {
				return (PostSelectionWithElementInfoController.this.currentNr == this.stateNr);
			}
			
		}
		
		private int lastNr;
		
		
		public SelectionTask() {
			super("PostSelection with Model Updater"); // //$NON-NLS-1$
			setPriority(Job.SHORT);
			setSystem(true);
			setUser(false);
			
			this.lastNr= PostSelectionWithElementInfoController.this.currentNr= Integer.MIN_VALUE;
		}
		
		
		@Override
		protected synchronized IStatus run(final IProgressMonitor monitor) {
			ISourceUnit input= null;
			try {
				checkNewInput();
				
				final Data run;
				IgnoreActivation[] ignore= null;
				synchronized (PostSelectionWithElementInfoController.this.inputLock) {
					run= new Data(PostSelectionWithElementInfoController.this.input, PostSelectionWithElementInfoController.this.currentSelection, PostSelectionWithElementInfoController.this.currentNr);
					if (run.inputElement == null || run.selection == null
							|| (this.lastNr == run.stateNr && PostSelectionWithElementInfoController.this.newListeners.isEmpty())) {
						return Status.OK_STATUS;
					}
					
					if (!PostSelectionWithElementInfoController.this.ignoreList.isEmpty()) {
						int num= PostSelectionWithElementInfoController.this.ignoreList.size();
						ignore= PostSelectionWithElementInfoController.this.ignoreList.toArray(new IgnoreActivation[num]);
						for (int i= num-1; i >= 0; i--) {
							if (ignore[i].marked && ignore[i].nr != run.stateNr) {
								PostSelectionWithElementInfoController.this.ignoreList.remove(i);
								ignore[i]= null;
								num--;
							}
						}
						if (num == 0) {
							ignore= null;
						}
					}
					
					input= run.inputElement;
					input.connect(monitor);
				}
				if (run.getInputInfo() == null
						|| run.getInputInfo().getStamp().getSourceStamp() != input.getDocument(null).getModificationStamp()) {
					return Status.OK_STATUS;
				}
				
				ImIdentityList<ISelectionWithElementInfoListener> listeners= PostSelectionWithElementInfoController.this.newListeners.clearToList();
				if (run.stateNr != this.lastNr) {
					listeners= PostSelectionWithElementInfoController.this.listeners.toList();
					this.lastNr= run.stateNr;
				}
				ITER_LISTENER: for (final ISelectionWithElementInfoListener listener : listeners) {
					if (ignore != null) {
						for (int j= 0; j < ignore.length; j++) {
							if (ignore[j] != null && ignore[j].listener == listener) {
								continue ITER_LISTENER;
							}
						}
					}
					if (!run.isStillValid()) {
						return Status.CANCEL_STATUS;
					}
					try {
						listener.stateChanged(run);
					}
					catch (final Exception e) {
						logListenerError(e);
					}
				}
			}
			finally {
				if (input != null) {
					input.disconnect(monitor);
				}
			}
			
			return Status.OK_STATUS;
		}
		
		private void checkNewInput() {
			if (PostSelectionWithElementInfoController.this.inputChanged) {
				synchronized (PostSelectionWithElementInfoController.this.inputLock) {
					PostSelectionWithElementInfoController.this.inputChanged= false;
				}
				final ImIdentityList<ISelectionWithElementInfoListener> listeners= PostSelectionWithElementInfoController.this.listeners.toList();
				for (final ISelectionWithElementInfoListener listener : listeners) {
					try {
						listener.inputChanged();
					}
					catch (final Exception e) {
						logListenerError(e);
					}
				}
			}
		}
	}
	
	private class SelectionListener implements ISelectionChangedListener {
		
		private boolean active;
		
		@Override
		public void selectionChanged(final SelectionChangedEvent event) {
			if (!this.active) {
				return;
			}
			synchronized (PostSelectionWithElementInfoController.this) {
				if (PostSelectionWithElementInfoController.this.currentSelection != null && PostSelectionWithElementInfoController.this.currentSelection.getSelection().equals(event.getSelection())) {
					return;
				}
				PostSelectionWithElementInfoController.this.currentNr++;
				PostSelectionWithElementInfoController.this.currentSelection= event;
				PostSelectionWithElementInfoController.this.updateJob.schedule();
			}
		}
	}
	
	public class IgnoreActivation {
		
		private final ISelectionWithElementInfoListener listener;
		private boolean marked;
		private int nr;
		
		private IgnoreActivation(final ISelectionWithElementInfoListener listener) {
			this.listener= listener;
		}
		
		public void deleteNext() {
			this.nr= PostSelectionWithElementInfoController.this.currentNr;
			this.marked= true;
		}
		
		public void delete() {
			this.nr= PostSelectionWithElementInfoController.this.currentNr-1;
			this.marked= true;
			synchronized (PostSelectionWithElementInfoController.this.inputLock) {
				PostSelectionWithElementInfoController.this.ignoreList.remove(this);
			}
		}
		
	}
	
	private final IPostSelectionProvider selectionProvider;
	private final IModelElementInputProvider modelProvider;
	private final CopyOnWriteIdentityListSet<ISelectionWithElementInfoListener> listeners= new CopyOnWriteIdentityListSet<>();
	private final CopyOnWriteIdentityListSet<ISelectionWithElementInfoListener> newListeners= new CopyOnWriteIdentityListSet<>();
	private final Object inputLock= new Object();
	
	private final IModelElementInputListener elementChangeListener;
	private final SelectionListener selectionListener;
	private final SelectionListener postSelectionListener;
	private PostSelectionCancelExtension cancelExtension;
	
	private final List<IgnoreActivation> ignoreList= new ArrayList<>();
	
	private ISourceUnit input; // current input
	private boolean inputChanged;
	private SelectionChangedEvent currentSelection; // current selection
	private volatile int currentNr; // stamp to check, if information still up-to-date
	
	private final SelectionTask updateJob= new SelectionTask();
	
	
	public PostSelectionWithElementInfoController(final IModelElementInputProvider modelProvider,
			final IPostSelectionProvider selectionProvider, final PostSelectionCancelExtension cancelExt) {
		this.selectionProvider= selectionProvider;
		
		this.modelProvider= modelProvider;
		
		this.elementChangeListener= new IModelElementInputListener() {
			@Override
			public void elementChanged(final IModelElement element) {
				synchronized (PostSelectionWithElementInfoController.this.inputLock) {
					if (PostSelectionWithElementInfoController.this.updateJob.getState() == Job.WAITING) {
						PostSelectionWithElementInfoController.this.updateJob.cancel();
					}
					PostSelectionWithElementInfoController.this.input= (ISourceUnit) element;
					PostSelectionWithElementInfoController.this.inputChanged= true;
					PostSelectionWithElementInfoController.this.currentNr++;
					PostSelectionWithElementInfoController.this.currentSelection= null;
					PostSelectionWithElementInfoController.this.updateJob.schedule();
				}
			}
			@Override
			public void elementInitialInfo(final IModelElement element) {
				checkUpdate(element);
			}
			@Override
			public void elementUpdatedInfo(final IModelElement element, final IModelElementDelta delta) {
				checkUpdate(element);
			}
			private void checkUpdate(final IModelElement element) {
				synchronized (PostSelectionWithElementInfoController.this.inputLock) {
					PostSelectionWithElementInfoController.this.currentNr++;
					if (PostSelectionWithElementInfoController.this.currentSelection == null) {
						return;
					}
				}
				PostSelectionWithElementInfoController.this.updateJob.run(null);
			}
		};
		this.selectionListener= new SelectionListener();
		this.selectionListener.active= false;
		this.selectionProvider.addSelectionChangedListener(this.selectionListener);
		
		this.postSelectionListener= new SelectionListener();
		this.postSelectionListener.active= true;
		this.selectionProvider.addPostSelectionChangedListener(this.postSelectionListener);
		
		this.modelProvider.addListener(this.elementChangeListener);
		if (cancelExt != null) {
			this.cancelExtension= cancelExt;
			this.cancelExtension.controller= this;
			this.cancelExtension.init();
		}
	}
	
	
	public void setUpdateOnSelection(final boolean active) {
		this.selectionListener.active= active;
	}
	
	public void setUpdateOnPostSelection(final boolean active) {
		this.postSelectionListener.active= active;
	}
	
	public void cancel() {
		synchronized (this.inputLock) {
			this.currentNr++;
			this.currentSelection= null;
		}
	}
	
	public void dispose() {
		cancel();
		this.modelProvider.removeListener(this.elementChangeListener);
		this.selectionProvider.removeSelectionChangedListener(this.selectionListener);
		this.selectionProvider.removePostSelectionChangedListener(this.postSelectionListener);
		if (this.cancelExtension != null) {
			this.cancelExtension.dispose();
		}
		this.newListeners.clear();
		this.listeners.clear();
	}
	
	
	public void addListener(final ISelectionWithElementInfoListener listener) {
		this.listeners.add(listener);
		this.newListeners.add(listener);
		this.updateJob.schedule();
	}
	
	public void removeListener(final ISelectionWithElementInfoListener listener) {
		this.newListeners.remove(listener);
		this.listeners.remove(listener);
	}
	
	public IgnoreActivation ignoreNext(final ISelectionWithElementInfoListener listener) {
		final IgnoreActivation control= new IgnoreActivation(listener);
		this.ignoreList.add(control);
		return control;
	}
	
	
	private void logListenerError(final Throwable e) {
		StatusManager.getManager().handle(new Status(
				IStatus.ERROR, LTKUIPlugin.BUNDLE_ID, 0,
				"An error occurred when calling a registered listener.", e )); //$NON-NLS-1$
	}
	
}
