/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.ui;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;

import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;

import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJarEntryResource;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.util.JavaModelUtil;

/**
 * A base content provider for Java elements. It provides access to the
 * Java element hierarchy without listening to changes in the Java model.
 * If updating the presentation on Java model change is required than
 * clients have to subclass, listen to Java model changes and have to update
 * the UI using corresponding methods provided by the JFace viewers or their
 * own UI presentation.
 * <p>
 * The following Java element hierarchy is surfaced by this content provider:
 * <pre>
Java model (<code>IJavaModel</code>)
   Java project (<code>IJavaProject</code>)
      package fragment root (<code>IPackageFragmentRoot</code>)
         package fragment (<code>IPackageFragment</code>)
            compilation unit (<code>ICompilationUnit</code>)
            binary class file (<code>IClassFile</code>)
 * </pre>
 * <p>
 * Note that when the entire Java project is declared to be package fragment root,
 * the corresponding package fragment root element that normally appears between the
 * Java project and the package fragments is automatically filtered out.
 * </p>
 *
 * @since 2.0
 */
public class StandardJavaElementContentProvider implements ITreeContentProvider, IWorkingCopyProvider {

	protected static final Object[] NO_CHILDREN= new Object[0];
	protected boolean fProvideMembers;
	protected boolean fProvideWorkingCopy;

	/**
	 * Creates a new content provider. The content provider does not
	 * provide members of compilation units or class files.
	 */
	public StandardJavaElementContentProvider() {
		this(false);
	}

	/**
	 * @param provideMembers if <code>true</code> members below compilation units
	 * @param provideWorkingCopy if <code>true</code> working copies are provided
	 * @deprecated Use {@link #StandardJavaElementContentProvider(boolean)} instead.
	 * Since 3.0 compilation unit children are always provided as working copies. The Java Model
	 * does not support the 'original' mode anymore.
	 */
	@Deprecated
	public StandardJavaElementContentProvider(boolean provideMembers, boolean provideWorkingCopy) {
		this(provideMembers);
	}


	/**
	 * Creates a new <code>StandardJavaElementContentProvider</code>.
	 *
	 * @param provideMembers if <code>true</code> members below compilation units
	 * and class files are provided.
	 */
	public StandardJavaElementContentProvider(boolean provideMembers) {
		fProvideMembers= provideMembers;
		fProvideWorkingCopy= provideMembers;
	}

	/**
	 * Returns whether members are provided when asking
	 * for a compilation units or class file for its children.
	 *
	 * @return <code>true</code> if the content provider provides members;
	 * otherwise <code>false</code> is returned
	 */
	public boolean getProvideMembers() {
		return fProvideMembers;
	}

	/**
	 * Sets whether the content provider is supposed to return members
	 * when asking a compilation unit or class file for its children.
	 *
	 * @param b if <code>true</code> then members are provided.
	 * If <code>false</code> compilation units and class files are the
	 * leaves provided by this content provider.
	 */
	public void setProvideMembers(boolean b) {
		//hello
		fProvideMembers= b;
	}

	/**
	 * @return returns <code>true</code> if working copies are provided
	 * @deprecated Since 3.0 compilation unit children are always provided as working copies. The Java model
	 * does not support the 'original' mode anymore.
	 */
	@Deprecated
	public boolean getProvideWorkingCopy() {
		return fProvideWorkingCopy;
	}

	/**
	 * @param b specifies if working copies should be provided
	 * @deprecated Since 3.0 compilation unit children are always provided from the working copy. The Java model
	 * offers a unified world and does not support the 'original' mode anymore.
	 */
	@Deprecated
	public void setProvideWorkingCopy(boolean b) {
		fProvideWorkingCopy= b;
	}

	@Override
	public boolean providesWorkingCopies() {
		return getProvideWorkingCopy();
	}

	@Override
	public Object[] getElements(Object parent) {
		return getChildren(parent);
	}

	@Override
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
	}

	@Override
	public void dispose() {
	}

	@Override
	public Object[] getChildren(Object element) {
		if (!exists(element))
			return NO_CHILDREN;

		try {
			if (element instanceof IJavaModel)
				return getJavaProjects((IJavaModel)element);

			if (element instanceof IJavaProject)
				return getPackageFragmentRoots((IJavaProject)element);

			if (element instanceof IPackageFragmentRoot)
				return getPackageFragmentRootContent((IPackageFragmentRoot)element);

			if (element instanceof IPackageFragment)
				return getPackageContent((IPackageFragment)element);

			if (element instanceof IFolder)
				return getFolderContent((IFolder)element);

			if (element instanceof IJarEntryResource) {
				return ((IJarEntryResource) element).getChildren();
			}

			if (getProvideMembers() && element instanceof ISourceReference && element instanceof IParent) {
				return ((IParent)element).getChildren();
			}
		} catch (CoreException e) {
			return NO_CHILDREN;
		}
		return NO_CHILDREN;
	}

	@Override
	public boolean hasChildren(Object element) {
		if (getProvideMembers()) {
			// assume CUs and class files are never empty
			if (element instanceof ICompilationUnit ||
				element instanceof IClassFile) {
				return true;
			}
		} else {
			// don't allow to drill down into a compilation unit or class file
			if (element instanceof ICompilationUnit ||
				element instanceof IClassFile ||
				element instanceof IFile)
			return false;
		}

		if (element instanceof IJavaProject) {
			IJavaProject jp= (IJavaProject)element;
			if (!jp.getProject().isOpen()) {
				return false;
			}
		}

		if (element instanceof IParent) {
			try {
				// when we have Java children return true, else we fetch all the children
				if (((IParent)element).hasChildren())
					return true;
			} catch(JavaModelException e) {
				return true;
			}
		}
		Object[] children= getChildren(element);
		return (children != null) && children.length > 0;
	}

	@Override
	public Object getParent(Object element) {
		if (!exists(element))
			return null;
		return internalGetParent(element);
	}

	/**
	 * Evaluates all children of a given {@link IPackageFragmentRoot}. Clients can override this method.
	 * @param root The root to evaluate the children for.
	 * @return The children of the root
	 * @exception JavaModelException if the package fragment root does not exist or if an
	 *      exception occurs while accessing its corresponding resource
	 *
	 * @since 3.3
	 */
	protected Object[] getPackageFragmentRootContent(IPackageFragmentRoot root) throws JavaModelException {
		IJavaElement[] fragments= root.getChildren();
		if (JavaModelUtil.is9OrHigher(root.getJavaProject())) {
			ITypeRoot moduleRoot= getModuleRoot(root);
			if (moduleRoot != null) {
				IJavaElement defaultPackage= moduleRoot.getParent();
				if (!JavaModelUtil.containsOrdinaryCompilationUnit((IPackageFragment) defaultPackage)) {
					// replace "empty" default package with module-info
					for (int i= 0; i < fragments.length; i++) {
						if (fragments[i].equals(defaultPackage)) {
							fragments= Arrays.copyOf(fragments, fragments.length);
							fragments[i]= moduleRoot;
							break;
						}
					}
				} else {
					// add module-info
					int length= fragments.length;
					fragments= Arrays.copyOf(fragments, length+1);
					fragments[length]= moduleRoot;
				}
			}
		}
		if (isProjectPackageFragmentRoot(root)) {
			return fragments;
		}
		Object[] nonJavaResources= root.getNonJavaResources();
		if (nonJavaResources == null)
			return fragments;
		return concatenate(fragments, nonJavaResources);
	}

	ITypeRoot getModuleRoot(IPackageFragmentRoot root) throws JavaModelException {
		IJavaElement module= root.getModuleDescription();
		if (module == null) {
			// may still need to show an empty module-info.java, which otherwise would remain invisible
			IPackageFragment dfltPack= root.getPackageFragment(""); //$NON-NLS-1$
			if (dfltPack.exists()) {
				for (IJavaElement child : dfltPack.getChildren()) {
					if (child instanceof ITypeRoot
							&& JavaModelUtil.isModuleInfo((ITypeRoot) child)
							&& ((ITypeRoot) child).getChildren().length == 0) {
						return (ITypeRoot) child;
					}
				}
			}
			return null;
		} else {
			return (ITypeRoot) module.getParent();
		}
	}

	/**
	 * Evaluates all children of a given {@link IJavaProject}. Clients can override this method.
	 * @param project The Java project to evaluate the children for.
	 * @return The children of the project. Typically these are package fragment roots but can also be other elements.
	 * @exception JavaModelException if the Java project does not exist or if an
	 *      exception occurs while accessing its corresponding resource
	 */
	protected Object[] getPackageFragmentRoots(IJavaProject project) throws JavaModelException {
		if (!project.getProject().isOpen())
			return NO_CHILDREN;

		IPackageFragmentRoot[] roots= project.getPackageFragmentRoots();
		List<Object> list= new ArrayList<>(roots.length);
		// filter out package fragments that correspond to projects and
		// replace them with the package fragments directly
		for (int i= 0; i < roots.length; i++) {
			IPackageFragmentRoot root= roots[i];
			if (isProjectPackageFragmentRoot(root)) {
				Object[] fragments= getPackageFragmentRootContent(root);
				list.addAll(Arrays.asList(fragments));
			} else {
				list.add(root);
			}
		}
		Object[] resources= project.getNonJavaResources();
		list.addAll(Arrays.asList(resources));
		return list.toArray();
	}

	/**
	 * Evaluates all Java projects of a given {@link IJavaModel}. Clients can override this method.
	 *
	 * @param jm the Java model
	 * @return the projects
	 * @throws JavaModelException thrown if accessing the model failed
	 */
	protected Object[] getJavaProjects(IJavaModel jm) throws JavaModelException {
		return jm.getJavaProjects();
	}

	/**
	 * Evaluates all children of a given {@link IPackageFragment}. Clients can override this method.
	 * @param fragment The fragment to evaluate the children for.
	 * @return The children of the given package fragment.
	 * @exception JavaModelException if the package fragment does not exist or if an
	 *      exception occurs while accessing its corresponding resource
	 *
	 * @since 3.3
	 */
	protected Object[] getPackageContent(IPackageFragment fragment) throws JavaModelException {
		if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) {
			ITypeRoot[] compilationUnits= filterModuleInfo(fragment, fragment.getCompilationUnits());
			return concatenate(compilationUnits, fragment.getNonJavaResources());
		}
		ITypeRoot[] classFiles= fragment.getOrdinaryClassFiles();
		return concatenate(classFiles, fragment.getNonJavaResources());
	}

	private ITypeRoot[] filterModuleInfo(IPackageFragment fragment, ITypeRoot[] units) {
		if (fragment.isDefaultPackage() && JavaModelUtil.is9OrHigher(fragment.getJavaProject())) {
			int count= 0;
			ITypeRoot[] newUnits= new ITypeRoot[units.length];
			for (int i= 0; i < units.length; i++) {
				if (!JavaModelUtil.isModuleInfo(units[i]))
					newUnits[count++]= units[i];
			}
			if (count < units.length)
				return Arrays.copyOf(newUnits, count);
		}
		return units;
	}

	/**
	 * Evaluates all children of a given {@link IFolder}. Clients can override this method.
	 * @param folder The folder to evaluate the children for.
	 * @return The children of the given folder.
	 * @exception CoreException if the folder does not exist.
	 *
	 * @since 3.3
	 */
	protected Object[] getFolderContent(IFolder folder) throws CoreException {
		IResource[] members= folder.members();
		IJavaProject javaProject= JavaCore.create(folder.getProject());
		if (javaProject == null || !javaProject.exists())
			return members;
		boolean isFolderOnClasspath = javaProject.isOnClasspath(folder);
		List<IResource> nonJavaResources= new ArrayList<>();
		// Can be on classpath but as a member of non-java resource folder
		for (int i= 0; i < members.length; i++) {
			IResource member= members[i];
			// A resource can also be a java element
			// in the case of exclusion and inclusion filters.
			// We therefore exclude Java elements from the list
			// of non-Java resources.
			if (isFolderOnClasspath) {
				if (javaProject.findPackageFragmentRoot(member.getFullPath()) == null) {
					nonJavaResources.add(member);
				}
			} else if (!javaProject.isOnClasspath(member)) {
				nonJavaResources.add(member);
			} else {
				IJavaElement element= JavaCore.create(member, javaProject);
				if (element instanceof IPackageFragmentRoot
						&& javaProject.equals(element.getJavaProject())
						&& ((IPackageFragmentRoot)element).getKind() != IPackageFragmentRoot.K_SOURCE) {
					// don't skip libs and class folders on the classpath of their project
					nonJavaResources.add(member);
				}
			}
		}
		return nonJavaResources.toArray();
	}

	/**
	 * Tests if the a Java element delta contains a class path change
	 *
	 * @param delta the Java element delta
	 * @return returns <code>true</code> if the delta contains a class path change
	 */
	protected boolean isClassPathChange(IJavaElementDelta delta) {

		// need to test the flags only for package fragment roots
		if (delta.getElement().getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT)
			return false;

		int flags= delta.getFlags();
		return (delta.getKind() == IJavaElementDelta.CHANGED &&
			((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0) ||
			 ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) ||
			 ((flags & IJavaElementDelta.F_REORDER) != 0));
	}

	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 *
	 * @param root the package fragment root
	 * @return returns the element representing the root.
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	protected Object skipProjectPackageFragmentRoot(IPackageFragmentRoot root) {
		if (isProjectPackageFragmentRoot(root))
			return root.getParent();
		return root;
	}

	/**
	 * Tests if the given element is a empty package fragment.
	 *
	 * @param element the element to test
	 * @return returns <code>true</code> if the package fragment is empty
	 * @throws JavaModelException thrown if accessing the element failed
	 */
	protected boolean isPackageFragmentEmpty(IJavaElement element) throws JavaModelException {
		if (element instanceof IPackageFragment) {
			IPackageFragment fragment= (IPackageFragment)element;
			if (fragment.exists() && !(fragment.hasChildren() || fragment.getNonJavaResources().length > 0) && fragment.hasSubpackages())
				return true;
		}
		return false;
	}

	/**
	 * Tests if the package fragment root is located on the project.
	 *
	 * @param root the package fragment root
	 * @return returns <code>true</code> if the package fragment root is the located on the project
	 */
	protected boolean isProjectPackageFragmentRoot(IPackageFragmentRoot root) {
		IJavaProject javaProject= root.getJavaProject();
		return javaProject != null && javaProject.getPath().equals(root.getPath());
	}

	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 *
	 * @param element the element to test
	 * @return returns <code>true</code> if the element exists
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	protected boolean exists(Object element) {
		if (element == null) {
			return false;
		}
		if (element instanceof IResource) {
			return ((IResource)element).exists();
		}
		if (element instanceof IJavaElement) {
			return ((IJavaElement)element).exists();
		}
		return true;
	}

	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 *
	 * @param element the element
	 * @return the parent of the element
	 *
	 * @noreference This method is not intended to be referenced by clients.
	 */
	protected Object internalGetParent(Object element) {

		// try to map resources to the containing package fragment
		if (element instanceof IResource) {
			IResource parent= ((IResource)element).getParent();
			IJavaElement jParent= JavaCore.create(parent);
			// http://bugs.eclipse.org/bugs/show_bug.cgi?id=31374
			if (jParent != null && jParent.exists())
				return jParent;
			return parent;
		} else if (element instanceof IJavaElement) {
			IJavaElement parent= ((IJavaElement) element).getParent();
			// for package fragments that are contained in a project package fragment
			// we have to skip the package fragment root as the parent.
			if (element instanceof IPackageFragment) {
				return skipProjectPackageFragmentRoot((IPackageFragmentRoot) parent);
			}
			if (element instanceof ITypeRoot && JavaModelUtil.isModuleInfo((ITypeRoot) element)
					&& parent instanceof IPackageFragment && ((IPackageFragment) parent).isDefaultPackage()) {
				return parent.getParent(); // module-info in default package: skip the default package
			}
			return parent;
		} else if (element instanceof IJarEntryResource) {
			return ((IJarEntryResource) element).getParent();
		}
		return null;
	}

	/**
	 * Utility method to concatenate two arrays.
	 *
	 * @param a1 the first array
	 * @param a2 the second array
	 * @return the concatenated array
	 */
	protected static Object[] concatenate(Object[] a1, Object[] a2) {
		int a1Len= a1.length;
		int a2Len= a2.length;
		if (a1Len == 0) return a2;
		if (a2Len == 0) return a1;
		Object[] res= new Object[a1Len + a2Len];
		System.arraycopy(a1, 0, res, 0, a1Len);
		System.arraycopy(a2, 0, res, a1Len, a2Len);
		return res;
	}


}
