/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.ui.search;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.PerformanceStats;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.search.IDLTKSearchConstants;
import org.eclipse.dltk.core.search.SearchEngine;
import org.eclipse.dltk.core.search.SearchParticipant;
import org.eclipse.dltk.core.search.SearchPattern;
import org.eclipse.dltk.internal.corext.util.Messages;
import org.eclipse.dltk.internal.corext.util.SearchUtils;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.ScriptElementLabels;
import org.eclipse.dltk.ui.search.ElementQuerySpecification;
import org.eclipse.dltk.ui.search.IMatchPresentation;
import org.eclipse.dltk.ui.search.IQueryParticipant;
import org.eclipse.dltk.ui.search.ISearchRequestor;
import org.eclipse.dltk.ui.search.PatternQuerySpecification;
import org.eclipse.dltk.ui.search.QuerySpecification;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.ISearchResult;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.ui.text.Match;


public class DLTKSearchQuery implements ISearchQuery {

	private static final String PERF_SEARCH_PARTICIPANT= "org.eclipse.dltk.ui/perf/search/participants"; //$NON-NLS-1$

	private ISearchResult fResult;
	private final QuerySpecification fPatternData;

	public DLTKSearchQuery(QuerySpecification data) {
		if (data == null) {
			throw new IllegalArgumentException("data must not be null"); //$NON-NLS-1$
		}
		fPatternData= data;
	}

	private static class SearchRequestor implements ISearchRequestor {
		private IQueryParticipant fParticipant;
		private DLTKSearchResult fSearchResult;

		@Override
		public void reportMatch(Match match) {
			IMatchPresentation participant= fParticipant.getUIParticipant();
			if (participant == null || match.getElement() instanceof IModelElement || match.getElement() instanceof IResource) {
				fSearchResult.addMatch(match);
			} else {
				fSearchResult.addMatch(match, participant);
			}
		}

		protected SearchRequestor(IQueryParticipant participant, DLTKSearchResult result) {
			super();
			fParticipant= participant;
			fSearchResult= result;
		}
	}

	@Override
	public IStatus run(IProgressMonitor monitor) {
		final DLTKSearchResult textResult= (DLTKSearchResult) getSearchResult();
		textResult.removeAll();
		// Don't need to pass in working copies in 3.0 here
		SearchEngine engine= new SearchEngine();
		try {

			int totalTicks= 1000;
			IProject[] projects= DLTKSearchScopeFactory.getInstance().getProjects(fPatternData.getScope());
			final SearchParticipantRecord[] participantDescriptors = SearchParticipantsExtensionPoint
					.getInstance().getSearchParticipants(this.fPatternData.getScope().getLanguageToolkit(), projects);
			final int[] ticks= new int[participantDescriptors.length];
			for (int i= 0; i < participantDescriptors.length; i++) {
				final int iPrime= i;
				ISafeRunnable runnable= new ISafeRunnable() {
					@Override
					public void handleException(Throwable exception) {
						ticks[iPrime]= 0;
						String message= SearchMessages.DLTKSearchQuery_error_participant_estimate;
						DLTKUIPlugin.log(new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, message, exception));
					}

					@Override
					public void run() throws Exception {
						ticks[iPrime]= participantDescriptors[iPrime].getParticipant().estimateTicks(fPatternData);
					}
				};

				SafeRunner.run(runnable);
				totalTicks+= ticks[i];
			}

			SearchPattern pattern;
			String stringPattern;

			IDLTKLanguageToolkit toolkit = this.fPatternData.getScope().getLanguageToolkit();
			if (fPatternData instanceof ElementQuerySpecification) {
				IModelElement element= ((ElementQuerySpecification) fPatternData).getElement();
				stringPattern= ScriptElementLabels.getDefault().getElementLabel(element, ScriptElementLabels.ALL_DEFAULT);
				if (!element.exists()) {
					return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, Messages.format(SearchMessages.DLTKSearchQuery_error_element_does_not_exist, stringPattern), null);
				}
				pattern= SearchPattern.createPattern(element, fPatternData.getLimitTo(), SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE, toolkit);
			} else {
				PatternQuerySpecification patternSpec = (PatternQuerySpecification) fPatternData;
				stringPattern= patternSpec.getPattern();
				int matchMode= getMatchMode(stringPattern) | SearchPattern.R_ERASURE_MATCH;
				if (patternSpec.isCaseSensitive())
					matchMode |= SearchPattern.R_CASE_SENSITIVE;

				pattern= SearchPattern.createPattern(patternSpec.getPattern(), patternSpec.getSearchFor(), patternSpec.getLimitTo(), matchMode, toolkit);
			}

			if (pattern == null) {
				return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, Messages.format(SearchMessages.DLTKSearchQuery_error_unsupported_pattern, stringPattern), null);
			}
			monitor.beginTask(Messages.format(SearchMessages.DLTKSearchQuery_task_label, stringPattern), totalTicks);
			IProgressMonitor mainSearchPM= new SubProgressMonitor(monitor, 1000);

			boolean ignorePotentials= NewSearchUI.arePotentialMatchesIgnored();
			NewSearchResultCollector collector= new NewSearchResultCollector(textResult, ignorePotentials);


			engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, fPatternData.getScope(), collector, mainSearchPM);
			for (int i= 0; i < participantDescriptors.length; i++) {
				final ISearchRequestor requestor= new SearchRequestor(participantDescriptors[i].getParticipant(), textResult);
				final IProgressMonitor participantPM= new SubProgressMonitor(monitor, ticks[i]);

				final int iPrime= i;
				ISafeRunnable runnable= new ISafeRunnable() {
					@Override
					public void handleException(Throwable exception) {
						participantDescriptors[iPrime].getDescriptor().disable();
						String message= SearchMessages.DLTKSearchQuery_error_participant_search;
						DLTKUIPlugin.log(new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, message, exception));
					}

					@Override
					public void run() throws Exception {

						final IQueryParticipant participant= participantDescriptors[iPrime].getParticipant();

						final PerformanceStats stats= PerformanceStats.getStats(PERF_SEARCH_PARTICIPANT, participant);
						stats.startRun();

						participant.search(requestor, fPatternData, participantPM);

						stats.endRun();
					}
				};

				SafeRunner.run(runnable);
			}

		} catch (CoreException e) {
			return e.getStatus();
		}
		String message= Messages.format(SearchMessages.DLTKSearchQuery_status_ok_message, String.valueOf(textResult.getMatchCount()));
		return new Status(IStatus.OK, DLTKUIPlugin.getPluginId(), 0, message, null);
	}

	private int getMatchMode(String pattern) {
		if (pattern.indexOf('*') != -1 || pattern.indexOf('?') != -1) {
			return SearchPattern.R_PATTERN_MATCH;
		} else if (SearchUtils.isCamelCasePattern(pattern)) {
			return SearchPattern.R_CAMELCASE_MATCH;
		}
		return SearchPattern.R_EXACT_MATCH;
	}

	@Override
	public String getLabel() {
		return SearchMessages.DLTKSearchQuery_label;
	}

	public String getResultLabel(int nMatches) {
		if (nMatches == 1) {
			String[] args= { getSearchPatternDescription(), fPatternData.getScopeDescription() };
			switch (fPatternData.getLimitTo()) {
//				case IDLTKSearchConstants.IMPLEMENTORS:
//					return Messages.format(SearchMessages.DLTKSearchOperation_singularImplementorsPostfix, args);
				case IDLTKSearchConstants.DECLARATIONS:
					return Messages.format(SearchMessages.DLTKSearchOperation_singularDeclarationsPostfix, args);
				case IDLTKSearchConstants.REFERENCES:
					return Messages.format(SearchMessages.DLTKSearchOperation_singularReferencesPostfix, args);
				case IDLTKSearchConstants.ALL_OCCURRENCES:
					return Messages.format(SearchMessages.DLTKSearchOperation_singularOccurrencesPostfix, args);
//				case IDLTKSearchConstants.READ_ACCESSES:
//					return Messages.format(SearchMessages.DLTKSearchOperation_singularReadReferencesPostfix, args);
//				case IDLTKSearchConstants.WRITE_ACCESSES:
//					return Messages.format(SearchMessages.DLTKSearchOperation_singularWriteReferencesPostfix, args);
				default:
					return Messages.format(SearchMessages.DLTKSearchOperation_singularOccurrencesPostfix, args);
			}
		} else {
			Object[] args= { getSearchPatternDescription(), Integer.valueOf(nMatches), fPatternData.getScopeDescription() };
			switch (fPatternData.getLimitTo()) {
//				case IDLTKSearchConstants.IMPLEMENTORS:
//					return Messages.format(SearchMessages.DLTKSearchOperation_pluralImplementorsPostfix, args);
				case IDLTKSearchConstants.DECLARATIONS:
					return Messages.format(SearchMessages.DLTKSearchOperation_pluralDeclarationsPostfix, args);
				case IDLTKSearchConstants.REFERENCES:
					return Messages.format(SearchMessages.DLTKSearchOperation_pluralReferencesPostfix, args);
				case IDLTKSearchConstants.ALL_OCCURRENCES:
					return Messages.format(SearchMessages.DLTKSearchOperation_pluralOccurrencesPostfix, args);
//				case IDLTKSearchConstants.READ_ACCESSES:
//					return Messages.format(SearchMessages.DLTKSearchOperation_pluralReadReferencesPostfix, args);
//				case IDLTKSearchConstants.WRITE_ACCESSES:
//					return Messages.format(SearchMessages.DLTKSearchOperation_pluralWriteReferencesPostfix, args);
				default:
					return Messages.format(SearchMessages.DLTKSearchOperation_pluralOccurrencesPostfix, args);
			}
		}
	}

	private String getSearchPatternDescription() {
		if (fPatternData instanceof ElementQuerySpecification) {
			IModelElement element= ((ElementQuerySpecification) fPatternData).getElement();
			return ScriptElementLabels.getDefault().getElementLabel(element, ScriptElementLabels.ALL_DEFAULT
					| ScriptElementLabels.ALL_FULLY_QUALIFIED | ScriptElementLabels.USE_RESOLVED);
		}
		return ((PatternQuerySpecification) fPatternData).getPattern();
	}

	ImageDescriptor getImageDescriptor() {
		if (/*fPatternData.getLimitTo() == IDLTKSearchConstants.IMPLEMENTORS ||*/ fPatternData.getLimitTo() == IDLTKSearchConstants.DECLARATIONS)
			return DLTKPluginImages.DESC_OBJS_SEARCH_DECL;
		else
			return DLTKPluginImages.DESC_OBJS_SEARCH_REF;
	}

	@Override
	public boolean canRerun() {
		return true;
	}

	@Override
	public boolean canRunInBackground() {
		return true;
	}

	@Override
	public ISearchResult getSearchResult() {
		if (fResult == null) {
			fResult= new DLTKSearchResult(this);
			new SearchResultUpdater((DLTKSearchResult) fResult);
		}
		return fResult;
	}

	QuerySpecification getSpecification() {
		return fPatternData;
	}
}
