/*******************************************************************************
 * Copyright (c) 2011 Tasktop Technologies.
 * 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:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.sandbox.search.ui.provider;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
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.SubMonitor;
import org.eclipse.mylyn.sandbox.search.ui.SearchCallback;
import org.eclipse.mylyn.sandbox.search.ui.SearchCriteria;
import org.eclipse.mylyn.sandbox.search.ui.SearchProvider;
import org.eclipse.mylyn.sandbox.search.ui.SearchResult;
import org.eclipse.osgi.util.NLS;

/**
 * A search provider that operates over java.io
 * 
 * @author David Green
 */
public class BasicSearchProvider extends SearchProvider {

	private abstract class FileMatcher {
		public abstract boolean matches(IFileStore file, IProgressMonitor monitor);
	}

	private class CompositeFileMatcher extends FileMatcher {

		private final List<FileMatcher> delegates;

		private final boolean allMatch;

		/**
		 * @param allMatch
		 *            indicate if one delegate must match (false) or if all delegates must match (true)
		 */
		public CompositeFileMatcher(boolean allMatch) {
			this.allMatch = allMatch;
			delegates = new ArrayList<FileMatcher>();
		}

		public CompositeFileMatcher(List<FileMatcher> delegates, boolean allMatch) {
			this.delegates = delegates;
			this.allMatch = allMatch;
		}

		public void add(FileMatcher matcher) {
			delegates.add(matcher);
		}

		@Override
		public boolean matches(IFileStore file, IProgressMonitor monitor) {
			for (FileMatcher matcher : delegates) {
				if (monitor.isCanceled()) {
					return false;
				}
				if (!matcher.matches(file, monitor)) {
					if (allMatch) {
						return false;
					}
				} else if (!allMatch) {
					return true;
				}
			}
			return allMatch ? true : false;
		}
	}

	private class FileNameMatcher extends FileMatcher {

		private final Pattern pattern;

		public FileNameMatcher(String matchPattern) {
			String regex = ".*?"; //$NON-NLS-1$
			regex += patternToRegex(matchPattern);
			regex += ".*"; //$NON-NLS-1$
			pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		}

		@Override
		public boolean matches(IFileStore file, IProgressMonitor monitor) {
			String name = file.getName();
			return pattern.matcher(name).matches();
		}

	}

	private class FileContentMatcher extends FileMatcher {

		private final Pattern pattern;

		private final int maxMatchingCharacters = 1024 * 16;

		public FileContentMatcher(SearchCriteria searchSpecification) {
			pattern = Pattern.compile(patternToRegex(searchSpecification.getText().trim()), Pattern.CASE_INSENSITIVE);
		}

		@Override
		public boolean matches(IFileStore file, IProgressMonitor monitor) {
			monitor.subTask(file.toString());
			try {
				InputStream inputStream = file.openInputStream(EFS.NONE, monitor);
				try {
					InputStreamReader reader = new InputStreamReader(new BufferedInputStream(inputStream));
					try {
						ReaderCharSequence charSequence = new ReaderCharSequence(maxMatchingCharacters, reader, monitor);
						return pattern.matcher(charSequence).find();
					} finally {
						reader.close();
					}
				} finally {
					inputStream.close();
				}
			} catch (IOException e) {
				// ignore
			} catch (CoreException e) {
				// ignore
			}
			return false;
		}

	}

	@Override
	public void performSearch(SearchCriteria searchSpecification, SearchCallback callback, IProgressMonitor m)
			throws CoreException {
		SubMonitor monitor = SubMonitor.convert(m);
		monitor.beginTask(NLS.bind(Messages.BasicSearchProvider_0, searchSpecification.getText()),
				searchSpecification.getMaximumResults() > 0
						? searchSpecification.getMaximumResults()
						: IProgressMonitor.UNKNOWN);
		try {
			FileMatcher matcher = computeMatcher(searchSpecification);

			File[] roots = File.listRoots();
			if (roots != null) {
				int matchCount = 0;

				Stack<IFileStore> state = new Stack<IFileStore>();

				// reverse-order iteration so that the first one is the last pushed on the stack
				for (int x = roots.length - 1; x >= 0; --x) {
					if (monitor.isCanceled()) {
						break;
					}
					File root = roots[x];
					IFileStore fileStore = EFS.getLocalFileSystem().fromLocalFile(root);

					state.push(fileStore);
				}
				try {
					while (!state.isEmpty() && !monitor.isCanceled()) {
						IFileStore fileStore = state.pop();

						IFileInfo fileInfo = fileStore.fetchInfo();
						if (isDefaultIgnore(fileStore, fileInfo)) {
							// ignore
						} else if (fileInfo.isDirectory()) {
							monitor.subTask(fileStore.toString());

							IFileStore[] childStores = fileStore.childStores(EFS.NONE, monitor.newChild(0));
							for (IFileStore child : childStores) {
								state.push(child);
							}
						} else {

							if (matcher.matches(fileStore, monitor.newChild(0))) {
								monitor.worked(1);

								callback.searchResult(new SearchResult(fileStore.toLocalFile(EFS.NONE,
										monitor.newChild(0))));

								if (++matchCount >= searchSpecification.getMaximumResults()) {
									break;
								}
							}
						}
					}
				} catch (OperationCanceledException oce) {
					// ignore
				} catch (CoreException e) {
					if (e.getStatus().getSeverity() != IStatus.CANCEL) {
						throw e;
					}
				}
			}
		} finally {
			monitor.done();
		}
	}

	private boolean isDefaultIgnore(IFileStore fileStore, IFileInfo fileInfo) {
		if (fileInfo.getAttribute(EFS.ATTRIBUTE_SYMLINK) || fileInfo.getAttribute(EFS.ATTRIBUTE_HIDDEN)) {
			// ignore, we don't follow symbolic links or hidden files
			return true;
		} else {
			String name = fileStore.getName();
			if (fileInfo.isDirectory()) {
				if ((name.equals("Windows") || name.equals("$Recycle.Bin")) && fileStore.getParent() != null && fileStore.getParent().getParent() == null) { //$NON-NLS-1$ //$NON-NLS-2$
					return true;
				} else if (name.startsWith(".")) { //$NON-NLS-1$
					return true;
				}
			} else {
				if (name.endsWith(".dll") || name.endsWith(".exe") || name.endsWith(".sys") || name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".bin")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
					return true;
				}
			}
		}
		return false;
	}

	private FileMatcher computeMatcher(SearchCriteria searchSpecification) {
		List<FileMatcher> filenameMatchers = new ArrayList<FileMatcher>();

		for (String filenamePattern : searchSpecification.getFilenamePatterns()) {
			if (filenamePattern.length() > 0) {
				if (filenamePattern.equals("*") || filenamePattern.equals("*.*")) { //$NON-NLS-1$//$NON-NLS-2$
					// every file matches
					filenameMatchers.clear();
					break;
				} else {
					filenameMatchers.add(new FileNameMatcher(filenamePattern));
				}
			}
		}

		CompositeFileMatcher fileMatcher = new CompositeFileMatcher(true);
		if (!filenameMatchers.isEmpty()) {
			fileMatcher.add(filenameMatchers.size() == 1 ? filenameMatchers.get(0) : new CompositeFileMatcher(
					filenameMatchers, false));
		}

		if (searchSpecification.getText() != null && searchSpecification.getText().trim().length() > 0) {
			fileMatcher.add(new FileContentMatcher(searchSpecification));
		}

		return fileMatcher;
	}

	private String patternToRegex(String matchPattern) {
		String regex = ""; //$NON-NLS-1$
		for (char c : matchPattern.toCharArray()) {
			if (Character.isLetterOrDigit(c)) {
				regex += c;
			} else {
				if (c == '*') {
					regex += ".*"; //$NON-NLS-1$
				} else if (c == '?') {
					regex += "."; //$NON-NLS-1$
				} else {
					regex += "\\"; //$NON-NLS-1$
					regex += c;
				}
			}
		}
		return regex;
	}
}
