/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
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) {
			Object[] 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);
			}
		}
		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;
		}
		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;
	}
}
