/*******************************************************************************
 * Copyright (c) 2016, 2019 Zend Technologies 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
 * 
 * Contributors:
 *     Zend Technologies - initial API and implementation
 *******************************************************************************/
package org.eclipse.dltk.internal.core.index.lucene;

import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.BDV_DOC;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.BDV_ELEMENT_NAME;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.BDV_METADATA;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.BDV_PARENT;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.BDV_PATH;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.BDV_QUALIFIER;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.F_CC_NAME;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.F_ELEMENT_NAME_LC;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.F_PARENT;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.F_PATH;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.F_QUALIFIER;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.NDV_FLAGS;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.NDV_LENGTH;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.NDV_NAME_LENGTH;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.NDV_NAME_OFFSET;
import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.NDV_OFFSET;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafCollector;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorable;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.SearcherManager;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.util.BytesRef;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.dltk.core.ScriptModelUtil;
import org.eclipse.dltk.core.index2.search.ISearchEngineExtension;
import org.eclipse.dltk.core.index2.search.ISearchRequestor;
import org.eclipse.dltk.core.search.IDLTKSearchScope;
import org.eclipse.dltk.internal.core.search.DLTKSearchScope;

/**
 * Lucene based implementation for DLTK search engine.
 * 
 * @author Michal Niewrzal, Bartlomiej Laczkowski
 */
@SuppressWarnings("restriction")
public class LuceneSearchEngine implements ISearchEngineExtension {

	private static final class SearchScope {

		static List<String> getContainers(IDLTKSearchScope scope) {
			List<String> containers = new ArrayList<>();
			for (IPath path : scope.enclosingProjectsAndZips()) {
				containers.add(path.toString());
			}
			return containers;
		}

		static List<String> getScripts(IDLTKSearchScope scope) {
			List<String> scripts = new ArrayList<>();
			if (scope instanceof DLTKSearchScope) {
				String[] relativePaths = ((DLTKSearchScope) scope)
						.getRelativePaths();
				String[] fileExtensions = ScriptModelUtil
						.getFileExtensions(scope.getLanguageToolkit());
				for (String relativePath : relativePaths) {
					if (relativePath.length() > 0) {
						if (fileExtensions != null) {
							boolean isScriptFile = false;
							for (String ext : fileExtensions) {
								if (relativePath.endsWith("." + ext)) { //$NON-NLS-1$
									isScriptFile = true;
									break;
								}
							}
							if (!isScriptFile) {
								break;
							}
						}
						scripts.add(relativePath);
					}
				}
			}
			return scripts;
		}

	}

	private static final class ResultsCollector implements Collector {

		private static final String[] NUMERIC_FIELDS = new String[] {
				NDV_OFFSET, NDV_LENGTH, NDV_FLAGS, NDV_NAME_OFFSET,
				NDV_NAME_LENGTH };
		private static final String[] BINARY_FIELDS = new String[] { BDV_PATH,
				BDV_ELEMENT_NAME, BDV_QUALIFIER, BDV_PARENT, BDV_METADATA,
				BDV_DOC };
		private Map<String, NumericDocValues> fDocNumericValues;
		private Map<String, BinaryDocValues> fDocBinaryValues;
		private String fContainer;
		private int fElementType;
		private List<SearchMatch> fResult = new LinkedList<>();

		public ResultsCollector(String container, int elementType) {
			this.fContainer = container;
			this.fElementType = elementType;
		}

		public List<SearchMatch> getfResult() {
			return fResult;
		}

		@Override
		public ScoreMode scoreMode() {
			return ScoreMode.COMPLETE_NO_SCORES;
		}

		@Override
		public LeafCollector getLeafCollector(final LeafReaderContext context)
				throws IOException {
			final LeafReader reader = context.reader();
			fDocNumericValues = new HashMap<>();
			for (String field : NUMERIC_FIELDS) {
				NumericDocValues docValues = reader.getNumericDocValues(field);
				if (docValues != null) {
					fDocNumericValues.put(field, docValues);
				}
			}
			fDocBinaryValues = new HashMap<>();
			for (String field : BINARY_FIELDS) {
				BinaryDocValues docValues = reader.getBinaryDocValues(field);
				if (docValues != null) {
					fDocBinaryValues.put(field, docValues);
				}
			}
			return new LeafCollector() {

				@Override
				public void setScorer(Scorable scorable) throws IOException {
				}

				@Override
				public void collect(int docId) throws IOException {
					addResult(docId);
				}
			};
		}

		private void addResult(int docId) {
			fResult.add(new SearchMatch(fContainer, fElementType,
					getNumericValue(NDV_OFFSET, docId),
					getNumericValue(NDV_LENGTH, docId),
					getNumericValue(NDV_NAME_OFFSET, docId),
					getNumericValue(NDV_NAME_LENGTH, docId),
					getNumericValue(NDV_FLAGS, docId),
					getStringValue(BDV_ELEMENT_NAME, docId),
					getStringValue(BDV_PATH, docId),
					getStringValue(BDV_PARENT, docId),
					getStringValue(BDV_QUALIFIER, docId),
					getStringValue(BDV_DOC, docId),
					getStringValue(BDV_METADATA, docId)));
		}

		private long getNumericValue(String field, int docId) {
			NumericDocValues docValues = fDocNumericValues.get(field);
			if (docValues != null) {
				try {
					docValues.advanceExact(docId);
					if (!docValues.advanceExact(docId)) {
						return 0;
					}
					return docValues.longValue();
				} catch (IOException e) {
					Logger.logException(e);
				}
			}
			return 0;
		}

		private String getStringValue(String field, int docId) {
			BinaryDocValues docValues = fDocBinaryValues.get(field);
			if (docValues != null) {
				try {
					if (!docValues.advanceExact(docId)) {
						return null;
					}
					BytesRef bytesRef = docValues.binaryValue();
					if (bytesRef.length > 0)
						return bytesRef.utf8ToString();
				} catch (IOException e) {
					Logger.logException(e);
				}

			}
			return null;
		}

	}

	@Override
	public void search(int elementType, String qualifier, String elementName,
			int trueFlags, int falseFlags, int limit, SearchFor searchFor,
			MatchRule matchRule, IDLTKSearchScope scope,
			ISearchRequestor requestor, IProgressMonitor monitor) {
		search(elementType, qualifier, elementName, null, trueFlags, falseFlags,
				limit, searchFor, matchRule, scope, requestor, monitor);
	}

	@Override
	public void search(int elementType, String qualifier, String elementName,
			String parent, int trueFlags, int falseFlags, int limit,
			SearchFor searchFor, MatchRule matchRule, IDLTKSearchScope scope,
			ISearchRequestor requestor, IProgressMonitor monitor) {
		boolean searchForDecls = searchFor == SearchFor.DECLARATIONS
				|| searchFor == SearchFor.ALL_OCCURRENCES;
		boolean searchForRefs = searchFor == SearchFor.REFERENCES
				|| searchFor == SearchFor.ALL_OCCURRENCES;

		List<SearchTask> tasks = new LinkedList<>();
		List<String> containers = SearchScope.getContainers(scope);
		List<String> scripts = SearchScope.getScripts(scope);
		final SearchMatchHandler searchMatchHandler = new SearchMatchHandler(
				scope, requestor);
		if (searchForRefs) {
			for (String container : containers) {
				tasks.add(new SearchTask(elementType, qualifier, elementName,
						parent, trueFlags, falseFlags, true, matchRule, scripts,
						container));
			}
			ForkJoinTask.invokeAll(tasks).stream().forEach(t -> t.join()
					.stream().forEach(m -> searchMatchHandler.handle(m, true)));

		}
		if (searchForDecls) {
			for (String container : containers) {
				tasks.add(new SearchTask(elementType, qualifier, elementName,
						parent, trueFlags, falseFlags, false, matchRule,
						scripts, container));
			}
			ForkJoinTask.invokeAll(tasks).stream().forEach(t -> t.join()
					.stream().forEach(m -> searchMatchHandler.handle(m, true)));
		}
	}

	private Query createQuery(final String elementName, final String qualifier,
			final String parent, final int trueFlags, final int falseFlags,
			final boolean searchForRefs, MatchRule matchRule,
			List<String> scripts) {
		BooleanQuery.Builder queryBuilder = new BooleanQuery.Builder();
		if (!scripts.isEmpty()) {
			BooleanQuery.Builder scriptQueryBuilder = new BooleanQuery.Builder();
			for (String script : scripts) {
				scriptQueryBuilder.add(new TermQuery(new Term(F_PATH, script)),
						Occur.FILTER);
			}
			queryBuilder.add(scriptQueryBuilder.build(), Occur.FILTER);
		}
		if (elementName != null && !elementName.isEmpty()) {
			String elementNameLC = elementName.toLowerCase();
			Query nameQuery = null;
			Term nameCaseInsensitiveTerm = new Term(F_ELEMENT_NAME_LC,
					elementNameLC);
			if (matchRule == MatchRule.PREFIX) {
				nameQuery = new PrefixQuery(nameCaseInsensitiveTerm);
			} else if (matchRule == MatchRule.EXACT) {
				nameQuery = new TermQuery(nameCaseInsensitiveTerm);
			} else if (matchRule == MatchRule.CAMEL_CASE) {
				nameQuery = new PrefixQuery(new Term(F_CC_NAME, elementName));
			} else if (matchRule == MatchRule.PATTERN) {
				nameQuery = new WildcardQuery(nameCaseInsensitiveTerm);
			} else {
				throw new UnsupportedOperationException();
			}
			if (nameQuery != null) {
				queryBuilder.add(nameQuery, Occur.FILTER);
			}
		}
		if (qualifier != null && !qualifier.isEmpty()) {
			queryBuilder.add(new TermQuery(new Term(F_QUALIFIER, qualifier)),
					Occur.FILTER);
		}
		if (parent != null && !parent.isEmpty()) {
			queryBuilder.add(new TermQuery(new Term(F_PARENT, parent)),
					Occur.FILTER);
		}
		if (trueFlags != 0 || falseFlags != 0) {
			queryBuilder.add(new BitFlagsQuery(trueFlags, falseFlags),
					Occur.FILTER);
		}
		BooleanQuery query = queryBuilder.build();
		return query.clauses().isEmpty() ? null : query;
	}

	private class SearchTask extends RecursiveTask<List<SearchMatch>> {
		int elementType;
		String qualifier;
		String elementName;
		String parent;
		int trueFlags;
		int falseFlags;
		boolean searchForRefs;
		MatchRule matchRule;
		List<String> scripts;
		String container;

		private SearchTask(int elementType, String qualifier,
				String elementName, String parent, int trueFlags,
				final int falseFlags, boolean searchForRefs,
				MatchRule matchRule, List<String> scripts, String container) {
			this.elementType = elementType;
			this.qualifier = qualifier;
			this.elementName = elementName;
			this.parent = parent;
			this.trueFlags = trueFlags;
			this.falseFlags = falseFlags;
			this.searchForRefs = searchForRefs;
			this.matchRule = matchRule;
			this.scripts = scripts;
			this.container = container;
		}

		@Override
		protected List<SearchMatch> compute() {
			SearcherManager searcherManager = LuceneManager.INSTANCE
					.findIndexSearcher(container,
							searchForRefs ? IndexType.REFERENCES
									: IndexType.DECLARATIONS,
							elementType);
			if (searcherManager == null) {
				return Collections.emptyList();
			}
			IndexSearcher indexSearcher = null;
			try {
				indexSearcher = searcherManager.acquire();
				Query query = createQuery(elementName, qualifier, parent,
						trueFlags, falseFlags, searchForRefs, matchRule,
						scripts);
				ResultsCollector collector = new ResultsCollector(container,
						elementType);
				if (query != null) {
					indexSearcher.search(query, collector);
				} else {
					indexSearcher.search(new MatchAllDocsQuery(), collector);
				}
				return collector.getfResult();
			} catch (IOException e) {
				Logger.logException(e);
			} finally {
				if (indexSearcher != null) {
					try {
						searcherManager.release(indexSearcher);
					} catch (IOException e) {
						Logger.logException(e);
					}
				}
			}
			return Collections.emptyList();
		}
	}

}
