/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.core.search;

import java.io.IOException;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.search.*;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.index.Index;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
import org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor;
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
import org.eclipse.jdt.internal.core.search.processing.IJob;
import org.eclipse.jdt.internal.core.search.processing.JobManager;
import org.eclipse.jdt.internal.core.util.Util;

public class PatternSearchJob implements IJob {

protected SearchPattern pattern;
protected IJavaSearchScope scope;
protected SearchParticipant participant;
protected IndexQueryRequestor requestor;
protected boolean areIndexesReady;
protected long executionTime = 0;

public PatternSearchJob(SearchPattern pattern, SearchParticipant participant, IJavaSearchScope scope, IndexQueryRequestor requestor) {
	this.pattern = pattern;
	this.participant = participant;
	this.scope = scope;
	this.requestor = requestor;
}
public boolean belongsTo(String jobFamily) {
	return true;
}
public void cancel() {
	// search job is cancelled through progress 
}
public void ensureReadyToRun() {
	if (!this.areIndexesReady)
		getIndexes(null/*progress*/); // may trigger some index recreation
}
public boolean execute(IProgressMonitor progressMonitor) {
	if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();

	boolean isComplete = COMPLETE;
	executionTime = 0;
	Index[] indexes = getIndexes(progressMonitor);
	try {
		int max = indexes.length;
		if (progressMonitor != null)
			progressMonitor.beginTask("", max); //$NON-NLS-1$
		for (int i = 0; i < max; i++) {
			isComplete &= search(indexes[i], progressMonitor);
			if (progressMonitor != null) {
				if (progressMonitor.isCanceled()) throw new OperationCanceledException();
				progressMonitor.worked(1);
			}
		}
		if (JobManager.VERBOSE)
			Util.verbose("-> execution time: " + executionTime + "ms - " + this);//$NON-NLS-1$//$NON-NLS-2$
		return isComplete;
	} finally {
		if (progressMonitor != null)
			progressMonitor.done();
	}
}
public Index[] getIndexes(IProgressMonitor progressMonitor) {
	// acquire the in-memory indexes on the fly
	IPath[] indexLocations = this.participant.selectIndexes(this.pattern, this.scope);
	int length = indexLocations.length;
	Index[] indexes = new Index[length];
	int count = 0;
	IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
	for (int i = 0; i < length; i++) {
		if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();
		// may trigger some index recreation work
		String indexLocation = indexLocations[i].toOSString();
		IPath containerPath = (IPath) indexManager.indexLocations.keyForValue(indexLocation);
		Index index = indexManager.getIndex(containerPath, indexLocations[i].toOSString(), true /*reuse index file*/, false /*do not create if none*/);
		if (index != null)
			indexes[count++] = index; // only consider indexes which are ready
	}
	if (count == length) 
		this.areIndexesReady = true;
	else
		System.arraycopy(indexes, 0, indexes=new Index[count], 0, count);
	return indexes;
}	
public boolean search(Index index, IProgressMonitor progressMonitor) {
	if (index == null) return COMPLETE;
	if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();

	ReadWriteMonitor monitor = index.monitor;
	if (monitor == null) return COMPLETE; // index got deleted since acquired
	try {
		monitor.enterRead(); // ask permission to read
		long start = System.currentTimeMillis();
		MatchLocator.findIndexMatches(this.pattern, index, requestor, this.participant, this.scope, progressMonitor);
		executionTime += System.currentTimeMillis() - start;
		return COMPLETE;
	} catch (IOException e) {
		if (e instanceof java.io.EOFException)
			e.printStackTrace();
		return FAILED;
	} finally {
		monitor.exitRead(); // finished reading
	}
}
public String toString() {
	return "searching " + pattern.toString(); //$NON-NLS-1$
}
}
