/*******************************************************************************
 * Copyright (c) 2000, 2015 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.internal.ui.browsing;

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

import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;

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

import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.ui.JavaPlugin;

/**
 * Tree content provider for the hierarchical layout in the packages view.
 * <p>
 * XXX: The standard Java browsing part content provider needs and calls
 * the browsing part/view. This class currently doesn't need to do so
 * but might be required to later.
 * </p>
 */
class PackagesViewHierarchicalContentProvider extends LogicalPackagesProvider implements ITreeContentProvider {

	public PackagesViewHierarchicalContentProvider(StructuredViewer viewer){
		super(viewer);
	}

	/*
	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(Object)
	 */
	@Override
	public Object[] getChildren(Object parentElement) {
		try {
			if (parentElement instanceof IJavaElement) {
				IJavaElement iJavaElement= (IJavaElement) parentElement;
				int type= iJavaElement.getElementType();

				switch (type) {
					case IJavaElement.JAVA_PROJECT :
						{

							//create new element mapping
							fMapToLogicalPackage.clear();
							fMapToPackageFragments.clear();
							IJavaProject project= (IJavaProject) parentElement;

							List<IPackageFragment> list= new ArrayList<>();
							for (IPackageFragment fragment : getTopLevelChildrenByElementName(project.getPackageFragments())) {
								IJavaElement el= fragment.getParent();
								if (el instanceof IPackageFragmentRoot) {
									IPackageFragmentRoot root= (IPackageFragmentRoot) el;
									if (!root.isArchive() || !root.isExternal())
										list.add(fragment);
								}
							}

							List<Object> folders= new ArrayList<>();
							for (IPackageFragmentRoot root : project.getPackageFragmentRoots()) {
								IResource resource= root.getUnderlyingResource();
								if (resource != null && resource instanceof IFolder) {
									folders.addAll(getFolders(((IFolder)resource).members()));
								}
							}

							Object[] logicalPackages= combineSamePackagesIntoLogialPackages(list.toArray(new IPackageFragment[list.size()]));
							if (folders.size() > 0) {
								if (logicalPackages.length > 0)
									folders.addAll(Arrays.asList(logicalPackages));
								return folders.toArray();
							} else {
								return logicalPackages;
							}
						}

					case IJavaElement.PACKAGE_FRAGMENT_ROOT :
						{
							IPackageFragmentRoot root= (IPackageFragmentRoot) parentElement;

							//create new element mapping
							fMapToLogicalPackage.clear();
							fMapToPackageFragments.clear();
							IResource resource= root.getUnderlyingResource();
							if (root.isArchive() || root.isExternal()) {
								IJavaElement[] els= root.getChildren();
								IPackageFragment[] fragments= getTopLevelChildrenByElementName(els);
								addFragmentsToMap(fragments);
								return fragments;

							} else if (resource != null && resource instanceof IFolder) {
								List<IAdaptable> children= getFoldersAndElements(((IFolder)resource).members());

								IPackageFragment defaultPackage= root.getPackageFragment(""); //$NON-NLS-1$
								if(defaultPackage.exists())
									children.add(defaultPackage);

								addFragmentsToMap(children);
								return children.toArray();
							} else {
								return NO_CHILDREN;
							}
						}

					case IJavaElement.PACKAGE_FRAGMENT :
						{
							IPackageFragment packageFragment= (IPackageFragment) parentElement;
							if (packageFragment.isDefaultPackage())
								return NO_CHILDREN;

							IPackageFragmentRoot parent= (IPackageFragmentRoot) packageFragment.getParent();
							IPackageFragment[] fragments= findNextLevelChildrenByElementName(parent, packageFragment);

							addFragmentsToMap(fragments);

							Object[] nonJavaResources= packageFragment.getNonJavaResources();
							if (nonJavaResources.length == 0) {
								return fragments;
							}
							ArrayList<Object> combined= new ArrayList<>();
							combined.addAll(Arrays.asList(fragments));
							for (Object curr : nonJavaResources) {
								if (curr instanceof IFolder) {
									combined.add(curr);
								}
							}
							return combined.toArray();
						}
				}

			//@Improve: rewrite using concatenate
			} else if (parentElement instanceof LogicalPackage) {

				List<IPackageFragment> children= new ArrayList<>();
				LogicalPackage logicalPackage= (LogicalPackage) parentElement;
				for (IPackageFragment fragment : logicalPackage.getFragments()) {
					IPackageFragment[] objects= findNextLevelChildrenByElementName((IPackageFragmentRoot) fragment.getParent(), fragment);
					children.addAll(Arrays.asList(objects));
				}
				return combineSamePackagesIntoLogialPackages(children.toArray(new IPackageFragment[children.size()]));
			} else if (parentElement instanceof IFolder) {
				IFolder folder= (IFolder)parentElement;
				IResource[] resources= folder.members();
				List<IAdaptable> children = getFoldersAndElements(resources);
				addFragmentsToMap(children);
				return children.toArray();
			}

		} catch (CoreException e) {
			return NO_CHILDREN;
		}
		return NO_CHILDREN;
	}

	private void addFragmentsToMap(List<IAdaptable> elements) {
		List<IPackageFragment> packageFragments= new ArrayList<>();
		for (IAdaptable iAdaptable : elements) {
			Object elem= iAdaptable;
			if (elem instanceof IPackageFragment)
				packageFragments.add((IPackageFragment) elem);
		}
		addFragmentsToMap(packageFragments.toArray(new IPackageFragment[packageFragments.size()]));
	}

	private List<IAdaptable> getFoldersAndElements(IResource[] resources) {
		List<IAdaptable> list= new ArrayList<>();
		for (IResource resource : resources) {
			if (resource instanceof IFolder) {
				IFolder folder= (IFolder) resource;
				IJavaElement element= JavaCore.create(folder);

				if (element instanceof IPackageFragment) {
					list.add(element);
				} else {
					list.add(folder);
				}
			}
		}
		return list;
	}

	private List<IFolder> getFolders(IResource[] resources) {
		List<IFolder> list= new ArrayList<>();
		for (IResource resource : resources) {
			if (resource instanceof IFolder) {
				IFolder folder= (IFolder) resource;
				IJavaElement element= JavaCore.create(folder);

				if (element == null) {
					list.add(folder);
				}
			}
		}
		return list;
	}

	private IPackageFragment[] findNextLevelChildrenByElementName(IPackageFragmentRoot parent, IPackageFragment fragment) {
		List<IPackageFragment> list= new ArrayList<>();
		try {

			String fragmentname= fragment.getElementName();
			for (IJavaElement element : parent.getChildren()) {
				if (element instanceof IPackageFragment) {
					IPackageFragment frag= (IPackageFragment) element;

					String name= element.getElementName();
					if (name.length() > fragmentname.length() && name.charAt(fragmentname.length()) == '.' && frag.exists() && !IPackageFragment.DEFAULT_PACKAGE_NAME.equals(fragmentname) && name.startsWith(fragmentname) && !name.equals(fragmentname)) {
						String tail= name.substring(fragmentname.length() + 1);
						if (!IPackageFragment.DEFAULT_PACKAGE_NAME.equals(tail) && tail.indexOf('.') == -1) {
							list.add(frag);
						}
					}
				}
			}

		} catch (JavaModelException e) {
			JavaPlugin.log(e);
		}
		return list.toArray(new IPackageFragment[list.size()]);
	}

	private IPackageFragment[] getTopLevelChildrenByElementName(IJavaElement[] elements){
		List<IJavaElement> topLevelElements= new ArrayList<>();
		for (IJavaElement iJavaElement : elements) {
			//if the name of the PackageFragment is the top level package it will contain no "." separators
			if (iJavaElement instanceof IPackageFragment && iJavaElement.getElementName().indexOf('.')==-1){
				topLevelElements.add(iJavaElement);
			}
		}
		return topLevelElements.toArray(new IPackageFragment[topLevelElements.size()]);
	}

	/*
	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(Object)
	 */
	@Override
	public Object getParent(Object element) {

		if (element instanceof IPackageFragment) {
			IPackageFragment fragment= (IPackageFragment) element;
			if(!fragment.exists())
				return null;
			Object parent= getHierarchicalParent(fragment);
			if(parent instanceof IPackageFragment) {
				IPackageFragment pkgFragment= (IPackageFragment)parent;
				LogicalPackage logicalPkg= findLogicalPackage(pkgFragment);
				if (logicalPkg != null)
					return logicalPkg;
				else {
					LogicalPackage lp= createLogicalPackage(pkgFragment);
					if(lp == null)
						return pkgFragment;
					else return lp;
				}
			}
			return parent;

		} else if(element instanceof LogicalPackage){
			LogicalPackage el= (LogicalPackage) element;
			IPackageFragment fragment= el.getFragments()[0];
			Object parent= getHierarchicalParent(fragment);

			if(parent instanceof IPackageFragment){
				IPackageFragment pkgFragment= (IPackageFragment) parent;
				LogicalPackage logicalPkg= findLogicalPackage(pkgFragment);
				if (logicalPkg != null)
					return logicalPkg;
				else {
					LogicalPackage lp= createLogicalPackage(pkgFragment);
					if(lp == null)
						return pkgFragment;
					else return lp;
				}
			} else
				return fragment.getJavaProject();
		} else if (element instanceof IFolder) {
			IFolder folder = (IFolder) element;
			IResource res = folder.getParent();

			IJavaElement el = JavaCore.create(res);
			if (el != null) {
				return el;
			} else {
				return res;
			}
		}
		return null;
	}

	/*
	 * Check if the given IPackageFragment should be the member of a
	 * LogicalPackage and if so creates the LogicalPackage and adds it to the
	 * map.
	 */
	private LogicalPackage createLogicalPackage(IPackageFragment pkgFragment) {
		if(!fInputIsProject)
			return null;

		List<IPackageFragment> fragments= new ArrayList<>();
		try {
			for (IPackageFragmentRoot root : pkgFragment.getJavaProject().getPackageFragmentRoots()) {
				IPackageFragment fragment= root.getPackageFragment(pkgFragment.getElementName());
				if(fragment.exists() && !fragment.equals(pkgFragment))
					fragments.add(fragment);
			}
			if(!fragments.isEmpty()) {
				LogicalPackage logicalPackage= new LogicalPackage(pkgFragment);
				fMapToLogicalPackage.put(getKey(pkgFragment), logicalPackage);
				Iterator<IPackageFragment> iter= fragments.iterator();
				while(iter.hasNext()){
					IPackageFragment f= iter.next();
					if(logicalPackage.belongs(f)){
						logicalPackage.add(f);
						fMapToLogicalPackage.put(getKey(f), logicalPackage);
					}
				}

				return logicalPackage;
			}

		} catch (JavaModelException e) {
			JavaPlugin.log(e);
		}

		return null;
	}

	private Object getHierarchicalParent(IPackageFragment fragment) {
		IJavaElement parent= fragment.getParent();

		if ((parent instanceof IPackageFragmentRoot) && parent.exists()) {
			IPackageFragmentRoot root= (IPackageFragmentRoot) parent;
			if (root.isArchive() || root.isExternal() || !fragment.exists()) {
				return findNextLevelParentByElementName(fragment);
			} else {
				IResource resource= fragment.getResource();
				if ((resource != null) && (resource instanceof IFolder)) {
					IFolder folder= (IFolder) resource;
					IResource res= folder.getParent();

					IJavaElement el= JavaCore.create(res);
					if (el != null) {
						return el;
					} else {
						return res;
					}
				}
			}
		}
		return parent;
	}

	private Object findNextLevelParentByElementName(IPackageFragment child) {
		String name= child.getElementName();

		int index= name.lastIndexOf('.');
		if (index != -1) {
			String realParentName= name.substring(0, index);
			IPackageFragment element= ((IPackageFragmentRoot) child.getParent()).getPackageFragment(realParentName);
			if (element.exists()) {
				return element;
			}
		}
		return child.getParent();
	}


	/*
	 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(Object)
	 */
	@Override
	public boolean hasChildren(Object element) {

		if (element instanceof IPackageFragment) {
			IPackageFragment fragment= (IPackageFragment) element;
			if(fragment.isDefaultPackage() || !fragment.exists())
				return false;
		}
		return getChildren(element).length > 0;
	}

	/*
	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
	 */
	@Override
	public Object[] getElements(Object inputElement) {
		return getChildren(inputElement);
	}

	@Override
	protected void processDelta(IJavaElementDelta delta) throws JavaModelException {

		int kind = delta.getKind();
		final IJavaElement element = delta.getElement();

		if (isClassPathChange(delta)) {
			Object input= fViewer.getInput();
			if (input != null) {
				if (fInputIsProject && input.equals(element.getJavaProject())) {
					postRefresh(input);
					return;
				} else if (!fInputIsProject && input.equals(element)) {
					if (element.exists())
						postRefresh(input);
					else
						postRemove(input);
					return;
				}
			}
		}

		if (kind == IJavaElementDelta.REMOVED) {
			Object input= fViewer.getInput();
			if (input != null && input.equals(element)) {
					postRemove(input);
					return;
				}
		}

		if (element instanceof IPackageFragment) {
			final IPackageFragment frag = (IPackageFragment) element;

			//if fragment was in LogicalPackage refresh,
			//otherwise just remove
			switch (kind) {
				case IJavaElementDelta.REMOVED:
					removeElement(frag);
					return;
				case IJavaElementDelta.ADDED:
					Object parent= getParent(frag);
					addElement(frag, parent);
					return;
				case IJavaElementDelta.CHANGED:
					//just refresh
					LogicalPackage logicalPkg= findLogicalPackage(frag);
					//in case changed object is filtered out
					if (logicalPkg != null)
						postRefresh(findElementToRefresh(logicalPkg));
					else
						postRefresh(findElementToRefresh(frag));
					return;
				default:
					break;
			}
		}

		processAffectedChildren(delta);
	}

	private Object findElementToRefresh(Object object) {
		Object toBeRefreshed= object;
		if (fViewer.testFindItem(object) == null) {
			 Object parent= getParent(object);
			 if(parent instanceof IPackageFragmentRoot && fInputIsProject)
			 	parent= ((IPackageFragmentRoot)parent).getJavaProject();

			if(parent != null)
				toBeRefreshed= parent;
		}
		return toBeRefreshed;
	}

	private void processAffectedChildren(IJavaElementDelta delta) throws JavaModelException {
		for (IJavaElementDelta child : delta.getAffectedChildren()) {
			if (!(child instanceof ICompilationUnit)) {
				processDelta(child);
			}
		}
	}

	private void postAdd(final Object child, final Object parent) {
		postRunnable(() -> {
			Control ctrl = fViewer.getControl();
			if (ctrl != null && !ctrl.isDisposed()) {
				((TreeViewer)fViewer).add(parent, child);
			}
		});
	}

	private void postRemove(final Object object) {
		postRunnable(() -> {
			Control ctrl = fViewer.getControl();
			if (ctrl != null && !ctrl.isDisposed()) {
				((TreeViewer)fViewer).remove(object);
			}
		});
	}

	private void postRefresh(final Object object) {
		postRunnable(() -> {
			Control ctrl= fViewer.getControl();
			if (ctrl != null && !ctrl.isDisposed()) {
				((TreeViewer) fViewer).refresh(object);
			}
		});
	}

	private void postRunnable(final Runnable r) {
		Control ctrl= fViewer.getControl();
		if (ctrl != null && !ctrl.isDisposed()) {
		//	fBrowsingPart.setProcessSelectionEvents(false);
			try {
				Display currentDisplay= Display.getCurrent();
				if (currentDisplay != null && currentDisplay.equals(ctrl.getDisplay()))
					ctrl.getDisplay().syncExec(r);
				else
					ctrl.getDisplay().asyncExec(r);
			} finally {
		//		fBrowsingPart.setProcessSelectionEvents(true);
			}
		}
	}

	private void addElement(IPackageFragment frag, Object parent) {

		String key= getKey(frag);
		LogicalPackage lp= fMapToLogicalPackage.get(key);

		//if fragment must be added to an existing LogicalPackage
		if (lp != null && lp.belongs(frag)){
			lp.add(frag);
			return;
		}

		//if a new LogicalPackage must be created
		IPackageFragment iPackageFragment= fMapToPackageFragments.get(key);
		if (iPackageFragment!= null && !iPackageFragment.equals(frag)){
			lp= new LogicalPackage(iPackageFragment);
			lp.add(frag);
			//add new LogicalPackage to LogicalPackages map
			fMapToLogicalPackage.put(key, lp);

			//determine who to refresh
			if (parent instanceof IPackageFragmentRoot){
				IPackageFragmentRoot root= (IPackageFragmentRoot) parent;
				if (fInputIsProject){
					postRefresh(root.getJavaProject());
				} else {
					postRefresh(root);
				}
			} else {
				//@Improve: Should this be replaced by a refresh?
				postAdd(lp, parent);
				postRemove(iPackageFragment);
			}

		}
		//if this is a new Package Fragment
		else {
			fMapToPackageFragments.put(key, frag);

			//determine who to refresh
			if (parent instanceof IPackageFragmentRoot) {
				IPackageFragmentRoot root= (IPackageFragmentRoot) parent;
				if (fInputIsProject) {
					postAdd(frag, root.getJavaProject());
				} else
					postAdd(frag, root);
			} else {
				postAdd(frag, parent);
			}
		}
	}

	private void removeElement(IPackageFragment frag) {

		String key= getKey(frag);
		LogicalPackage lp= fMapToLogicalPackage.get(key);

		if(lp != null){
			lp.remove(frag);
			//if the LogicalPackage needs to revert back to a PackageFragment
			//remove it from the LogicalPackages map and add the PackageFragment
			//to the PackageFragment map
			if (lp.getFragments().length == 1) {
				IPackageFragment fragment= lp.getFragments()[0];
				fMapToPackageFragments.put(key, fragment);
				fMapToLogicalPackage.remove(key);

				//remove the LogicalPackage from viewer
				postRemove(lp);

				Object parent= getParent(fragment);
				if (parent instanceof IPackageFragmentRoot) {
					parent= ((IPackageFragmentRoot)parent).getJavaProject();
				}
				postAdd(fragment, parent);
			}

		} else {
			//remove the fragment from the fragment map and viewer
			IPackageFragment fragment= fMapToPackageFragments.get(key);
			if (fragment!= null && fragment.equals(frag)) {
				fMapToPackageFragments.remove(key);
				postRemove(frag);
			}
		}
	}
}
