/*******************************************************************************
 * Copyright (c) 2003, 2004 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
 * 
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.dialogs;

import java.util.ArrayList;
import java.util.HashSet;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchScope;

/**
 * This class was derived from JavaSearchScope as that class did not have a
 * provision to exclude classpath entries that are not exported A Java-specific
 * scope for searching relative to one or more java elements.
 */
public class TypeJavaSearchScope implements IJavaSearchScope {

	private boolean includeExportedClassPathEntriesOnly = true;

	private ArrayList elements;

	/*
	 * The paths of the resources in this search scope (or the classpath
	 * entries' paths if the resources are projects)
	 */
	private IPath[] paths;
	private boolean[] pathWithSubFolders;
	private int pathsCount;

	private IPath[] enclosingProjectsAndJars;

	public TypeJavaSearchScope() {
		this.initialize();

		// disabled for now as this could be expensive
		// JavaModelManager.getJavaModelManager().rememberScope(this);
	}

	private void addEnclosingProjectOrJar(IPath path) {
		int length = this.enclosingProjectsAndJars.length;
		for (int i = 0; i < length; i++) {
			if (this.enclosingProjectsAndJars[i].equals(path))
				return;
		}
		System.arraycopy(this.enclosingProjectsAndJars, 0, this.enclosingProjectsAndJars = new IPath[length + 1], 0, length);
		this.enclosingProjectsAndJars[length] = path;
	}

	/**
	 * Method addProject. This method adds all the classpath entries for the
	 * current project to the search scope.
	 * 
	 * @param javaProject
	 * @param includesPrereqProjects
	 * @param visitedProjects
	 * @throws JavaModelException
	 */
	public void addProject(IJavaProject javaProject, boolean includesPrereqProjects, HashSet visitedProjects) throws JavaModelException {
		IProject project = javaProject.getProject();
		if (!project.isAccessible() || !visitedProjects.add(project))
			return;

		this.addEnclosingProjectOrJar(project.getFullPath());

		IClasspathEntry[] entries = javaProject.getResolvedClasspath(true);
		IJavaModel model = javaProject.getJavaModel();
		for (int i = 0, length = entries.length; i < length; i++) {
			IClasspathEntry entry = entries[i];
			switch (entry.getEntryKind()) {
				case IClasspathEntry.CPE_LIBRARY :
					IPath path = entry.getPath();
					this.add(path, true);
					this.addEnclosingProjectOrJar(path);
					break;
				case IClasspathEntry.CPE_PROJECT :
					if (includesPrereqProjects) {
						this.add(model.getJavaProject(entry.getPath().lastSegment()), true, visitedProjects);
					}
					break;
				case IClasspathEntry.CPE_SOURCE :
					this.add(entry.getPath(), true);
					break;
			}
		}
	}

	/**
	 * Method add. This method filters out all the classpath entries of the
	 * project which are not exported.
	 * 
	 * @param javaProject
	 * @param includesPrereqProjects
	 * @param visitedProjects
	 * @throws JavaModelException
	 */
	public void add(IJavaProject javaProject, boolean includesPrereqProjects, HashSet visitedProjects) throws JavaModelException {
		IProject project = javaProject.getProject();
		if (!project.isAccessible() || !visitedProjects.add(project))
			return;

		this.addEnclosingProjectOrJar(project.getFullPath());

		IClasspathEntry[] entries = javaProject.getResolvedClasspath(true);
		IJavaModel model = javaProject.getJavaModel();
		for (int i = 0, length = entries.length; i < length; i++) {
			IClasspathEntry entry = entries[i];
			if (includeExportedClassPathEntriesOnly()) {
				if (!entry.isExported() && entry.getEntryKind() != IClasspathEntry.CPE_SOURCE)
					continue;
			}
			switch (entry.getEntryKind()) {
				case IClasspathEntry.CPE_LIBRARY :
					IPath path = entry.getPath();
					this.add(path, true);
					this.addEnclosingProjectOrJar(path);
					break;
				case IClasspathEntry.CPE_PROJECT :
					if (includesPrereqProjects) {
						this.add(model.getJavaProject(entry.getPath().lastSegment()), true, visitedProjects);
					}
					break;
				case IClasspathEntry.CPE_SOURCE :
					this.add(entry.getPath(), true);
					break;
			}
		}
	}
	public void add(IJavaElement element) throws JavaModelException {
		IPackageFragmentRoot root = null;
		switch (element.getElementType()) {
			case IJavaElement.JAVA_MODEL :
				// a workspace sope should be used
				break;
			case IJavaElement.JAVA_PROJECT :
				this.add((IJavaProject) element, true, new HashSet(2));
				break;
			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
				root = (IPackageFragmentRoot) element;
				this.add(root.getPath(), true);
				break;
			case IJavaElement.PACKAGE_FRAGMENT :
				root = (IPackageFragmentRoot) element.getParent();
				if (root.isArchive()) {
					this.add(root.getPath().append(new Path(element.getElementName().replace('.', '/'))), false);
				} else {
					IResource resource = element.getUnderlyingResource();
					if (resource != null && resource.isAccessible()) {
						this.add(resource.getFullPath(), false);
					}
				}
				break;
			default :
				// remember sub-cu (or sub-class file) java elements
				if (element instanceof IMember) {
					if (this.elements == null) {
						this.elements = new ArrayList();
					}
					this.elements.add(element);
				}
				this.add(this.fullPath(element), true);

				// find package fragment root including this java element
				IJavaElement parent = element.getParent();
				while (parent != null && !(parent instanceof IPackageFragmentRoot)) {
					parent = parent.getParent();
				}
				if (parent instanceof IPackageFragmentRoot) {
					root = (IPackageFragmentRoot) parent;
				}
		}

		if (root != null) {
			if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
				this.addEnclosingProjectOrJar(root.getPath());
			} else {
				this.addEnclosingProjectOrJar(root.getJavaProject().getProject().getFullPath());
			}
		}
	}

	/**
	 * Adds the given path to this search scope. Remember if subfolders need to
	 * be included as well.
	 */
	private void add(IPath path, boolean withSubFolders) {
		if (this.paths.length == this.pathsCount) {
			System.arraycopy(this.paths, 0, this.paths = new IPath[this.pathsCount * 2], 0, this.pathsCount);
			System.arraycopy(this.pathWithSubFolders, 0, this.pathWithSubFolders = new boolean[this.pathsCount * 2], 0, this.pathsCount);
		}
		this.paths[this.pathsCount] = path;
		this.pathWithSubFolders[this.pathsCount++] = withSubFolders;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see IJavaSearchScope#encloses(String)
	 */
	public boolean encloses(String resourcePathString) {
		IPath resourcePath;
		int separatorIndex = resourcePathString.indexOf(JAR_FILE_ENTRY_SEPARATOR);
		if (separatorIndex != -1) {
			resourcePath = new Path(resourcePathString.substring(0, separatorIndex)).append(new Path(resourcePathString.substring(separatorIndex + 1)));
		} else {
			resourcePath = new Path(resourcePathString);
		}
		return this.encloses(resourcePath);
	}

	/**
	 * Returns whether this search scope encloses the given path.
	 */
	private boolean encloses(IPath path) {
		for (int i = 0; i < this.pathsCount; i++) {
			if (this.pathWithSubFolders[i]) {
				if (this.paths[i].isPrefixOf(path)) {
					return true;
				}
			} else {
				IPath scopePath = this.paths[i];
				if (scopePath.isPrefixOf(path) && (scopePath.segmentCount() == path.segmentCount() - 1)) {
					return true;
				}
			}
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see IJavaSearchScope#encloses(IJavaElement)
	 */
	public boolean encloses(IJavaElement element) {
		if (this.elements != null) {
			for (int i = 0, length = this.elements.size(); i < length; i++) {
				IJavaElement scopeElement = (IJavaElement) this.elements.get(i);
				IJavaElement searchedElement = element;
				while (searchedElement != null) {
					if (searchedElement.equals(scopeElement)) {
						return true;
					} 
					searchedElement = searchedElement.getParent();
				}
			}
			return false;
		}
		return this.encloses(this.fullPath(element));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see IJavaSearchScope#enclosingProjectsAndJars()
	 */
	public IPath[] enclosingProjectsAndJars() {
		return this.enclosingProjectsAndJars;
	}
	private IPath fullPath(IJavaElement element) {
		if (element instanceof IPackageFragmentRoot) {
			return ((IPackageFragmentRoot) element).getPath();
		} 
		IJavaElement parent = element.getParent();
		IPath parentPath = parent == null ? null : this.fullPath(parent);
		IPath childPath;
		if (element instanceof IPackageFragment) {
			childPath = new Path(element.getElementName().replace('.', '/'));
		} else if (element instanceof IOpenable) {
			childPath = new Path(element.getElementName());
		} else {
			return parentPath;
		}
		return parentPath == null ? childPath : parentPath.append(childPath);
	}

	protected void initialize() {
		this.paths = new IPath[1];
		this.pathWithSubFolders = new boolean[1];
		this.pathsCount = 0;
		this.enclosingProjectsAndJars = new IPath[0];
	}
	/**
	 * Gets the includeExportedClassPathEntriesOnly.
	 * 
	 * @return Returns a boolean
	 */
	public boolean includeExportedClassPathEntriesOnly() {
		return includeExportedClassPathEntriesOnly;
	}

	/**
	 * Sets the includeExportedClassPathEntriesOnly.
	 * 
	 * @param includeExportedClassPathEntriesOnly
	 *            The includeExportedClassPathEntriesOnly to set
	 */
	public void setIncludeExportedClassPathEntriesOnly(boolean includeExportedClassPathEntriesOnly) {
		this.includeExportedClassPathEntriesOnly = includeExportedClassPathEntriesOnly;
	}
	/**
	 * @see IJavaSearchScope#includesBinaries()
	 * @deprecated
	 */
	public boolean includesBinaries() {
		return true;
	}

	/**
	 * @see IJavaSearchScope#includesClasspaths()
	 * @deprecated
	 */
	public boolean includesClasspaths() {
		return true;
	}

	/**
	 * @see IJavaSearchScope#setIncludesBinaries(boolean)
	 * @deprecated
	 */
	public void setIncludesBinaries(boolean includesBinaries) {
		//Default nothing
	}

	/**
	 * @see IJavaSearchScope#setIncludesClasspaths(boolean)
	 * @deprecated
	 */
	public void setIncludesClasspaths(boolean includesClasspaths) {
		//Default nothing
	}

}