/*******************************************************************************
 * Copyright (c) 2003, 2005 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
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * 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
	}

}
