/*******************************************************************************
 * 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
 *     Markus Schorn (Wind River Systems)
 *******************************************************************************/
package org.eclipse.search2.internal.ui;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;

import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;

import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;

import org.eclipse.search.internal.ui.SearchPlugin;
import org.eclipse.search.internal.ui.SearchPluginImages;
import org.eclipse.search.internal.ui.SearchPreferencePage;
import org.eclipse.search.ui.IQueryListener;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.ISearchResult;
import org.eclipse.search.ui.ISearchResultViewPart;

import org.eclipse.search2.internal.ui.text.PositionTracker;

public class InternalSearchUI {

	//The shared instance.
	private static InternalSearchUI fgInstance;

	// contains all running jobs
	private HashMap<ISearchQuery, SearchJobRecord> fSearchJobs;

	private QueryManager fSearchResultsManager;
	private PositionTracker fPositionTracker;

	private SearchViewManager fSearchViewManager;

	public static final Object FAMILY_SEARCH = new Object();

	private class SearchJobRecord {
		public ISearchQuery query;
		public Job job;
		public boolean isRunning;

		public SearchJobRecord(ISearchQuery job) {
			this.query= job;
			this.isRunning= false;
			this.job= null;
		}
	}


	private class InternalSearchJob extends Job {

		private SearchJobRecord fSearchJobRecord;

		public InternalSearchJob(SearchJobRecord sjr) {
			super(sjr.query.getLabel());

			fSearchJobRecord= sjr;
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			fSearchJobRecord.job= this;
			searchJobStarted(fSearchJobRecord);
			IStatus status= null;
			int origPriority= Thread.currentThread().getPriority();
			try {
				Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
			}
			catch (SecurityException e) {}
			try{
				status= fSearchJobRecord.query.run(monitor);
			} finally {
				try {
					Thread.currentThread().setPriority(origPriority);
				}
				catch (SecurityException e) {}
				searchJobFinished(fSearchJobRecord);
			}
			fSearchJobRecord.job= null;
			return status;
		}
		@Override
		public boolean belongsTo(Object family) {
			return family == InternalSearchUI.FAMILY_SEARCH;
		}

	}

	private void searchJobStarted(SearchJobRecord record) {
		record.isRunning= true;
		getSearchManager().queryStarting(record.query);
	}

	private void searchJobFinished(SearchJobRecord record) {
		record.isRunning= false;
		fSearchJobs.remove(record);
		getSearchManager().queryFinished(record.query);
	}

	/**
	 * The constructor.
	 */
	public InternalSearchUI() {
		fgInstance= this;
		fSearchJobs= new HashMap<>();
		fSearchResultsManager= new QueryManager();
		fPositionTracker= new PositionTracker();

		fSearchViewManager= new SearchViewManager(fSearchResultsManager);

		PlatformUI.getWorkbench().getProgressService().registerIconForFamily(SearchPluginImages.DESC_VIEW_SEARCHRES, FAMILY_SEARCH);
	}

	/**
	 * @return returns the shared instance.
	 */
	public static InternalSearchUI getInstance() {
		if (fgInstance ==null)
			fgInstance= new InternalSearchUI();
		return fgInstance;
	}

	public ISearchResultViewPart getSearchView() {
		return getSearchViewManager().getActiveSearchView();
	}

	private IWorkbenchSiteProgressService getProgressService() {
		ISearchResultViewPart view= getSearchView();
		if (view != null) {
			IWorkbenchPartSite site= view.getSite();
			if (site != null)
				return view.getSite().getAdapter(IWorkbenchSiteProgressService.class);
		}
		return null;
	}

	public boolean runSearchInBackground(ISearchQuery query, ISearchResultViewPart view) {
		if (isQueryRunning(query))
			return false;

		// prepare view
		if (view == null) {
			getSearchViewManager().activateSearchView(true);
		} else {
			getSearchViewManager().activateSearchView(view);
		}

		addQuery(query);

		SearchJobRecord sjr= new SearchJobRecord(query);
		fSearchJobs.put(query, sjr);

		Job job= new InternalSearchJob(sjr);
		job.setPriority(Job.BUILD);
		job.setUser(true);

		IWorkbenchSiteProgressService service= getProgressService();
		if (service != null) {
			service.schedule(job, 0, true);
		} else {
			job.schedule();
		}

		return true;
	}

	public boolean isQueryRunning(ISearchQuery query) {
		SearchJobRecord sjr= fSearchJobs.get(query);
		return sjr != null && sjr.isRunning;
	}

	public IStatus runSearchInForeground(IRunnableContext context, final ISearchQuery query, ISearchResultViewPart view) {
		if (isQueryRunning(query)) {
			return Status.CANCEL_STATUS;
		}

		// prepare view
		if (view == null) {
			getSearchViewManager().activateSearchView(true);
		} else {
			getSearchViewManager().activateSearchView(view);
		}

		addQuery(query);

		SearchJobRecord sjr= new SearchJobRecord(query);
		fSearchJobs.put(query, sjr);

		if (context == null)
			context= new ProgressMonitorDialog(null);

		return doRunSearchInForeground(sjr, context);
	}

	private IStatus doRunSearchInForeground(final SearchJobRecord rec, IRunnableContext context) {
		try {
			context.run(true, true, new IRunnableWithProgress() {
				@Override
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					searchJobStarted(rec);
					try {
						IStatus status= rec.query.run(monitor);
						if (status.matches(IStatus.CANCEL)) {
							throw new InterruptedException();
						}
						if (!status.isOK()) {
							throw new InvocationTargetException(new CoreException(status));
						}
					} catch (OperationCanceledException e) {
						throw new InterruptedException();
					} finally {
						searchJobFinished(rec);
					}
				}
			});
		} catch (InvocationTargetException e) {
			Throwable innerException= e.getTargetException();
			if (innerException instanceof CoreException) {
				return ((CoreException) innerException).getStatus();
			}
			return new Status(IStatus.ERROR, SearchPlugin.getID(), 0, SearchMessages.InternalSearchUI_error_unexpected, innerException);
		} catch (InterruptedException e) {
			return Status.CANCEL_STATUS;
		}
		return Status.OK_STATUS;
	}

	public static void shutdown() {
		InternalSearchUI instance= fgInstance;
		if (instance != null)
			instance.doShutdown();
	}

	private void doShutdown() {
		Iterator<SearchJobRecord> jobRecs= fSearchJobs.values().iterator();
		while (jobRecs.hasNext()) {
			SearchJobRecord element= jobRecs.next();
			if (element.job != null)
				element.job.cancel();
		}
		fPositionTracker.dispose();

		fSearchViewManager.dispose(fSearchResultsManager);

	}

	public void cancelSearch(ISearchQuery job) {
		SearchJobRecord rec= fSearchJobs.get(job);
		if (rec != null && rec.job != null)
			rec.job.cancel();
	}



	public QueryManager getSearchManager() {
		return fSearchResultsManager;
	}

	public SearchViewManager getSearchViewManager() {
		return fSearchViewManager;
	}

	public PositionTracker getPositionTracker() {
		return fPositionTracker;
	}

	public void addQueryListener(IQueryListener l) {
		getSearchManager().addQueryListener(l);
	}
	public ISearchQuery[] getQueries() {
		return getSearchManager().getQueries();
	}
	public void removeQueryListener(IQueryListener l) {
		getSearchManager().removeQueryListener(l);
	}

	public void removeQuery(ISearchQuery query) {
		if (query == null) {
			throw new IllegalArgumentException();
		}
		cancelSearch(query);
		getSearchManager().removeQuery(query);
		fSearchJobs.remove(query);
	}

	public void addQuery(ISearchQuery query) {
		if (query == null) {
			throw new IllegalArgumentException();
		}
		establishHistoryLimit();
		getSearchManager().addQuery(query);
	}

	private void establishHistoryLimit() {
		int historyLimit= SearchPreferencePage.getHistoryLimit();
		QueryManager searchManager= getSearchManager();
		if (historyLimit >= searchManager.getSize()) {
			return;
		}
		int numberQueriesNotShown= 0;
		SearchViewManager searchViewManager= getSearchViewManager();
		ISearchQuery[] queries= searchManager.getQueries();
		for (int i= 0; i < queries.length; i++) {
			ISearchQuery query= queries[i];
			if (!searchViewManager.isShown(query)) {
				if (++numberQueriesNotShown >= historyLimit) {
					removeQuery(query);
				}
			}
		}
	}

	public void removeAllQueries() {
		for (Iterator<ISearchQuery> queries= fSearchJobs.keySet().iterator(); queries.hasNext();) {
			ISearchQuery query= queries.next();
			cancelSearch(query);
		}
		fSearchJobs.clear();
		getSearchManager().removeAll();
	}

	public void showSearchResult(SearchView searchView, ISearchResult result, boolean openInNew) {
		if (openInNew)
			searchView= (SearchView)getSearchViewManager().activateSearchView(true, openInNew);
		showSearchResult(searchView, result);
	}

	private void showSearchResult(SearchView searchView, ISearchResult result) {
		getSearchManager().touch(result.getQuery());
		searchView.showSearchResult(result);
	}


}
