/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.search.internal.ui;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
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.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.viewers.Viewer;

import org.eclipse.ui.actions.WorkspaceModifyOperation;

import org.eclipse.search.internal.ui.util.ExceptionHandler;
import org.eclipse.search.ui.IGroupByKeyComputer;
import org.eclipse.search.ui.SearchUI;


/**
 * Manage search results
 * 	@deprecated old search
 */
@Deprecated
public class SearchManager implements IResourceChangeListener {

	static SearchManager fgDefault;

	Search fCurrentSearch= null;

	private SearchManager() {
		SearchPlugin.getWorkspace().addResourceChangeListener(this);
	}

	private HashSet<SearchResultViewer> fListeners= new HashSet<>();
	private LinkedList<Search> fPreviousSearches= new LinkedList<>();
	private boolean fIsRemoveAll= false;

	public static synchronized SearchManager getDefault() {
		if (fgDefault == null)
			fgDefault= new SearchManager();
		return fgDefault;
	}

	public void dispose() {
		SearchPlugin.getWorkspace().removeResourceChangeListener(this);
	}

	/**
	 * Returns the list with previous searches (ISearch).
	 * @return previous searches
	 */
	LinkedList<Search> getPreviousSearches() {
		return fPreviousSearches;
	}
	/**
	 * Returns the list with current (last) results
	 * @return the current results
	 */
	ArrayList<SearchResultViewEntry> getCurrentResults() {
		if (fCurrentSearch == null)
			return new ArrayList<>(0);
		return (ArrayList<SearchResultViewEntry>)fCurrentSearch.getResults();
	}

	public Search getCurrentSearch() {
		return fCurrentSearch;
	}

	void removeAllSearches() {
		SearchPlugin.getWorkspace().removeResourceChangeListener(this);
		WorkspaceModifyOperation op= new WorkspaceModifyOperation(null) {
			@Override
			protected void execute(IProgressMonitor monitor) throws CoreException {
				monitor.beginTask(SearchMessages.SearchManager_updating, 100);
				SearchPlugin.getWorkspace().getRoot().deleteMarkers(SearchUI.SEARCH_MARKER, true, IResource.DEPTH_INFINITE);
				monitor.worked(100);
				monitor.done();
			}
		};
		boolean isAutoBuilding= SearchPlugin.setAutoBuilding(false);
		try {
			ProgressMonitorDialog dialog= new ProgressMonitorDialog(getShell());
			dialog.run(true, true, op);
		} catch (InvocationTargetException ex) {
			ExceptionHandler.handle(ex, SearchMessages.Search_Error_deleteMarkers_title, SearchMessages.Search_Error_deleteMarkers_message);
		} catch (InterruptedException e) {
			// Do nothing. Operation has been canceled.
		} finally {
			SearchPlugin.getWorkspace().addResourceChangeListener(this);
			SearchPlugin.setAutoBuilding(isAutoBuilding);
		}

		// clear searches
		fPreviousSearches= new LinkedList<>();
		fCurrentSearch= null;

		// update viewers
		Iterator<SearchResultViewer> iter= fListeners.iterator();
		while (iter.hasNext()) {
			SearchResultViewer viewer= iter.next();
			handleAllSearchesRemoved(viewer);
		}
	}

	private void handleAllSearchesRemoved(SearchResultViewer viewer) {
		viewer.handleAllSearchesRemoved();
	}

	void setCurrentSearch(final Search search) {
		if (fCurrentSearch == search)
			return;

		SearchPlugin.getWorkspace().removeResourceChangeListener(this);
		WorkspaceModifyOperation op= new WorkspaceModifyOperation(null) {
			@Override
			protected void execute(IProgressMonitor monitor) throws CoreException {
				internalSetCurrentSearch(search, monitor);
			}
		};
		boolean isAutoBuilding= SearchPlugin.setAutoBuilding(false);
		try {
			ProgressMonitorDialog dialog= new ProgressMonitorDialog(getShell());
			dialog.run(true, true, op);
		} catch (InvocationTargetException ex) {
			ExceptionHandler.handle(ex, SearchMessages.Search_Error_switchSearch_title, SearchMessages.Search_Error_switchSearch_message);
		} catch (InterruptedException e) {
			// Do nothing. Operation has been canceled.
		} finally {
			SearchPlugin.setAutoBuilding(isAutoBuilding);
		}

		getPreviousSearches().remove(search);
		getPreviousSearches().addFirst(search);
	}

	void internalSetCurrentSearch(final Search search, IProgressMonitor monitor) {
		if (fCurrentSearch != null)
			fCurrentSearch.backupMarkers();

		final Search previousSearch= fCurrentSearch;
		fCurrentSearch= search;
		monitor.beginTask(SearchMessages.SearchManager_updating, getCurrentResults().size() + 20);

		// remove current search markers
		try {
			SearchPlugin.getWorkspace().getRoot().deleteMarkers(SearchUI.SEARCH_MARKER, true, IResource.DEPTH_INFINITE);
		} catch (CoreException ex) {
			ExceptionHandler.handle(ex, SearchMessages.Search_Error_deleteMarkers_title, SearchMessages.Search_Error_deleteMarkers_message);
		}
		monitor.worked(10);

		// add search markers
		Iterator<SearchResultViewEntry> iter= getCurrentResults().iterator();
		ArrayList<SearchResultViewEntry> emptyEntries= new ArrayList<>(10);
		boolean filesChanged= false;
		boolean filesDeleted= false;
		IGroupByKeyComputer groupByKeyComputer= getCurrentSearch().getGroupByKeyComputer();
		while (iter.hasNext()) {
			monitor.worked(1);
			SearchResultViewEntry entry= iter.next();
			Iterator<Map<String, Object>> attrPerMarkerIter= entry.getAttributesPerMarker().iterator();
			entry.clearMarkerList();
			if (entry.getResource() == null || !entry.getResource().exists()) {
				emptyEntries.add(entry);
				filesDeleted= true;
				continue;
			}
			while (attrPerMarkerIter.hasNext()) {
				IMarker newMarker= null;
				try {
					newMarker= entry.getResource().createMarker(entry.getMarkerType());
				} catch (CoreException ex) {
					ExceptionHandler.handle(ex, SearchMessages.Search_Error_createMarker_title, SearchMessages.Search_Error_createMarker_message);
					continue;
				}
				try {
					newMarker.setAttributes(attrPerMarkerIter.next());
					if (groupByKeyComputer !=null && groupByKeyComputer.computeGroupByKey(newMarker) == null) {
						filesDeleted= true;
						newMarker.delete();
						continue;
					}
				} catch (CoreException ex) {
					ExceptionHandler.handle(ex, SearchMessages.Search_Error_markerAttributeAccess_title, SearchMessages.Search_Error_markerAttributeAccess_message);
				}
				entry.add(newMarker);
			}
			if (entry.getMatchCount() == 0)
				emptyEntries.add(entry);
			else if (!filesChanged && entry.getResource().getModificationStamp() != entry.getModificationStamp())
				filesChanged= true;
		}
		getCurrentResults().removeAll(emptyEntries);
		monitor.worked(10);

		String warningMessage= null;
		Display display= getDisplay();

		if (filesChanged)
			warningMessage= SearchMessages.SearchManager_resourceChanged;
		if (filesDeleted) {
			if (warningMessage == null)
				warningMessage= ""; //$NON-NLS-1$
			else
				warningMessage += "\n";			 //$NON-NLS-1$
			warningMessage += SearchMessages.SearchManager_resourceDeleted;
		}
		if (warningMessage != null) {
			if (display != null && !display.isDisposed()) {
				final String warningTitle= SearchMessages.SearchManager_resourceChangedWarning;
				final String warningMsg= warningMessage;
				display.syncExec(new Runnable() {
					@Override
					public void run() {
						MessageDialog.openWarning(getShell(), warningTitle, warningMsg);
					}
				});
			}
		}

		// update viewers
		Iterator<SearchResultViewer> iter2= fListeners.iterator();
		if (display != null && !display.isDisposed()) {
			final Viewer visibleViewer= ((SearchResultView)SearchUI.getSearchResultView()).getViewer();
			while (iter2.hasNext()) {
				final SearchResultViewer viewer= iter2.next();
				display.syncExec(new Runnable() {
					@Override
					public void run() {
						if (previousSearch != null && viewer == visibleViewer)
							previousSearch.setSelection(viewer.getSelection());
						viewer.setInput(null);
						viewer.setPageId(search.getPageId());
						viewer.setGotoMarkerAction(search.getGotoMarkerAction());
						viewer.setContextMenuTarget(search.getContextMenuContributor());
						viewer.setActionGroupFactory(null);
						viewer.setInput(getCurrentResults());
						viewer.setActionGroupFactory(search.getActionGroupFactory());
						viewer.setSelection(fCurrentSearch.getSelection(), true);
					}
				});
			}
		}
		monitor.done();
	}

	/**
	 * Returns the number of matches
	 * @return the number of matches
	 */
	int getCurrentItemCount() {
		if (fCurrentSearch != null)
			return fCurrentSearch.getItemCount();
		return 0;
	}

	void removeAllResults() {
		fIsRemoveAll= true;
		try {
			SearchPlugin.getWorkspace().getRoot().deleteMarkers(SearchUI.SEARCH_MARKER, true, IResource.DEPTH_INFINITE);
		} catch (CoreException ex) {
			ExceptionHandler.handle(ex, SearchMessages.Search_Error_deleteMarkers_title, SearchMessages.Search_Error_deleteMarkers_message);
			fIsRemoveAll= false;
		}
	}

	void addNewSearch(final Search newSearch) {

		SearchPlugin.getWorkspace().removeResourceChangeListener(this);

		// Clear the viewers
		Iterator<SearchResultViewer> iter= fListeners.iterator();
		Display display= getDisplay();
		if (display != null && !display.isDisposed()) {
			final Viewer visibleViewer= ((SearchResultView)SearchUI.getSearchResultView()).getViewer();
			while (iter.hasNext()) {
				final SearchResultViewer viewer= iter.next();
				display.syncExec(new Runnable() {
					@Override
					public void run() {
						if (fCurrentSearch != null && viewer == visibleViewer)
							fCurrentSearch.setSelection(viewer.getSelection());
						setNewSearch(viewer, newSearch);
					}
				});
			}
		}

		if (fCurrentSearch != null) {
			if (fCurrentSearch.isSameSearch(newSearch))
				getPreviousSearches().remove(fCurrentSearch);
			else
				fCurrentSearch.backupMarkers();
		}
		fCurrentSearch= newSearch;
		getPreviousSearches().addFirst(fCurrentSearch);

		// Remove the markers
		try {
			SearchPlugin.getWorkspace().getRoot().deleteMarkers(SearchUI.SEARCH_MARKER, true, IResource.DEPTH_INFINITE);
		} catch (CoreException ex) {
			ExceptionHandler.handle(ex, SearchMessages.Search_Error_deleteMarkers_title, SearchMessages.Search_Error_deleteMarkers_message);
		}
	}

	void searchFinished(ArrayList<SearchResultViewEntry> results) {
		Assert.isNotNull(results);
		getCurrentSearch().setResults(results);

		Display display= getDisplay();
		if (display == null || display.isDisposed())
			return;

		if (Thread.currentThread() == display.getThread())
			handleNewSearchResult();
		else {
			display.syncExec(new Runnable() {
				@Override
				public void run() {
					handleNewSearchResult();
				}
			});
		}
		SearchPlugin.getWorkspace().addResourceChangeListener(this);
	}

	//--- Change event handling -------------------------------------------------

	void addSearchChangeListener(SearchResultViewer viewer) {
		fListeners.add(viewer);
	}

	void removeSearchChangeListener(SearchResultViewer viewer) {
		Assert.isNotNull(viewer);
		fListeners.remove(viewer);
	}

	private final void handleSearchMarkersChanged(IMarkerDelta[] markerDeltas) {
		if (fIsRemoveAll) {
			handleRemoveAll();
			fIsRemoveAll= false;
			return;
		}

		Iterator<SearchResultViewer> iter= fListeners.iterator();
		while (iter.hasNext())
			iter.next().getControl().setRedraw(false);

		for (int i=0; i < markerDeltas.length; i++) {
			handleSearchMarkerChanged(markerDeltas[i]);
		}

		iter= fListeners.iterator();
		while (iter.hasNext())
			iter.next().getControl().setRedraw(true);

	}

	private void handleSearchMarkerChanged(IMarkerDelta markerDelta) {
		int kind= markerDelta.getKind();
		// don't listen for adds will be done by ISearchResultView.addMatch(...)
		if (((kind & IResourceDelta.REMOVED) != 0))
			handleRemoveMatch(markerDelta.getMarker());
		else if ((kind & IResourceDelta.CHANGED) != 0)
			handleUpdateMatch(markerDelta.getMarker());
	}

	private void handleRemoveAll() {
		if (fCurrentSearch != null)
			fCurrentSearch.removeResults();
		Iterator<SearchResultViewer> iter= fListeners.iterator();
		while (iter.hasNext())
			iter.next().handleRemoveAll();
	}

	private void handleNewSearchResult() {
		Iterator<SearchResultViewer> iter= fListeners.iterator();
		while (iter.hasNext()) {
			SearchResultViewer viewer= iter.next();
			viewer.setInput(getCurrentResults());
		}
	}

	private void setNewSearch(SearchResultViewer viewer, Search search) {
		viewer.setInput(null);
		viewer.clearTitle();
		viewer.setPageId(search.getPageId());
		viewer.setGotoMarkerAction(search.getGotoMarkerAction());
		viewer.setContextMenuTarget(search.getContextMenuContributor());
		viewer.setActionGroupFactory(search.getActionGroupFactory());
	}

	private void handleRemoveMatch(IMarker marker) {
		SearchResultViewEntry entry= findEntry(marker);
		if (entry != null) {
			entry.remove(marker);
			if (entry.getMatchCount() == 0) {
				getCurrentResults().remove(entry);
				Iterator<SearchResultViewer> iter= fListeners.iterator();
				while (iter.hasNext())
					iter.next().handleRemoveMatch(entry);
			}
			else {
				Iterator<SearchResultViewer> iter= fListeners.iterator();
				while (iter.hasNext())
					iter.next().handleUpdateMatch(entry, true);
			}
		}
	}

	private void handleUpdateMatch(IMarker marker) {
		SearchResultViewEntry entry= findEntry(marker);
		if (entry != null) {
			Iterator<SearchResultViewer> iter= fListeners.iterator();
			while (iter.hasNext())
				iter.next().handleUpdateMatch(entry, false);
		}
	}

	private SearchResultViewEntry findEntry(IMarker marker) {
		Iterator<SearchResultViewEntry> entries= getCurrentResults().iterator();
		while (entries.hasNext()) {
			SearchResultViewEntry entry= entries.next();
			if (entry.contains(marker))
				return entry;
		}
		return null;
	}

	/**
	 * Received a resource event. Since the delta could be created in a
	 * separate thread this methods post the event into the viewer's
	 * display thread.
	 * @param event the event
	 */
	@Override
	public final void resourceChanged(final IResourceChangeEvent event) {
		if (event == null)
			return;

		final IMarkerDelta[] markerDeltas= event.findMarkerDeltas(SearchUI.SEARCH_MARKER, true);
		if (markerDeltas == null || markerDeltas.length < 1)
			return;

		Display display= getDisplay();
		if (display == null || display.isDisposed())
			return;

		Runnable runnable= new Runnable() {
			@Override
			public void run() {
				if (getCurrentSearch() != null) {
					handleSearchMarkersChanged(markerDeltas);
					// update title and actions
					Iterator<SearchResultViewer> iter= fListeners.iterator();
					while (iter.hasNext()) {
						SearchResultViewer viewer= iter.next();
						viewer.enableActions();
						viewer.updateTitle();
					}
				}
			}
		};
		display.syncExec(runnable);
	}
	/**
	 * Find and return a valid display
	 * @return the display
	 */
	private Display getDisplay() {
		Iterator<SearchResultViewer> iter= fListeners.iterator();
		while (iter.hasNext()) {
			Control control= ((Viewer)iter.next()).getControl();
			if (control != null && !control.isDisposed()) {
				Display display= control.getDisplay();
				if (display != null && !display.isDisposed())
					return display;
			}
		}
		return null;
	}
	/**
	 * Find and return a valid shell
	 * @return the shell
	 */
	private Shell getShell() {
		return SearchPlugin.getActiveWorkbenchShell();
	}
}

