/*******************************************************************************
 * Copyright (c) 2006, 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
 *     Frits Jalvingh - Contribution for Bug 459831 - [launching] Support attaching external annotations to a JRE container
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.jres;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.launching.LibraryLocation;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;

/**
 * Provides the content for the JREs selection/edit viewer
 *
 * @see ITreeContentProvider
 * @see VMDetailsDialog
 * @see VMLibraryBlock
 * @see LibraryLocation
 * @see LibraryStandin
 */
public class LibraryContentProvider implements ITreeContentProvider {

	private Viewer fViewer;

	/**
	 * Represents a sub-element of a <code>LibraryStandin</code>
	 */
	public class SubElement {

		public static final int JAVADOC_URL= 1;
		public static final int SOURCE_PATH= 2;
		public static final int EXTERNAL_ANNOTATIONS_PATH = 3;

		private LibraryStandin fParent;
		private int fType;

		public SubElement(LibraryStandin parent, int type) {
			fParent= parent;
			fType= type;
		}

		public LibraryStandin getParent() {
			return fParent;
		}

		public int getType() {
			return fType;
		}

		public void remove() {
			switch (fType) {
				case JAVADOC_URL:
					fParent.setJavadocLocation(null);
					break;
				case SOURCE_PATH:
					fParent.setSystemLibrarySourcePath(Path.EMPTY);
					break;
				case EXTERNAL_ANNOTATIONS_PATH:
					fParent.setExternalAnnotationsPath(Path.EMPTY);
					break;

			}
		}
	}

	private HashMap<LibraryStandin, Object[]> fChildren= new HashMap<>();

	private LibraryStandin[] fLibraries= new LibraryStandin[0];

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
	 */
	@Override
	public void dispose() {
		fChildren.clear();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
	 */
	@Override
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		fViewer = viewer;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
	 */
	@Override
	public Object[] getElements(Object inputElement) {
		return fLibraries;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
	 */
	@Override
	public Object[] getChildren(Object parentElement) {
		if (parentElement instanceof LibraryStandin) {
			LibraryStandin standin= (LibraryStandin) parentElement;
			Object[] children= fChildren.get(standin);
			if (children == null) {
				children = new Object[] { new SubElement(standin, SubElement.SOURCE_PATH), new SubElement(standin, SubElement.JAVADOC_URL),
						new SubElement(standin, SubElement.EXTERNAL_ANNOTATIONS_PATH) };
				fChildren.put(standin, children);
			}
			return children;
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
	 */
	@Override
	public Object getParent(Object element) {
		if (element instanceof SubElement) {
			return ((SubElement)element).getParent();
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
	 */
	@Override
	public boolean hasChildren(Object element) {
		return element instanceof LibraryStandin;
	}

	/**
	 * Sets the array of libraries to be the specified array of libraries
	 * @param libs the new array of libraries to set
	 */
	public void setLibraries(LibraryLocation[] libs) {
		fLibraries = new LibraryStandin[libs.length];
		for (int i = 0; i < libs.length; i++) {
			fLibraries[i] = new LibraryStandin(libs[i]);
		}
		if (fViewer != null) {
			fViewer.refresh();
		}
	}

	/**
	 * Returns the listing of <code>LibraryLocation</code>s
	 *
	 * @return the listing of <code>LibraryLocation</code>s, or an empty
	 * array, never <code>null</code>
	 */
	public LibraryLocation[] getLibraries() {
		LibraryLocation[] locations = new LibraryLocation[fLibraries.length];
		for (int i = 0; i < locations.length; i++) {
			locations[i] = fLibraries[i].toLibraryLocation();
		}
		return locations;
	}

	/**
	 * Returns the list of libraries in the given selection. SubElements
	 * are replaced by their parent libraries.
	 * @param selection the current selection
	 *
	 * @return the current set of selected <code>LibraryStandin</code>s from
	 * the current viewer selection, or an empty set, never <code>null</code>
	 */
	private Set<Object> getSelectedLibraries(IStructuredSelection selection) {
		Set<Object> libraries= new HashSet<>();
		for (Iterator<?> iter= selection.iterator(); iter.hasNext();) {
			Object element= iter.next();
			if (element instanceof LibraryStandin) {
				libraries.add(element);
			} else if (element instanceof SubElement) {
				libraries.add(((SubElement)element).getParent());
			}
		}
		return libraries;
	}

	/**
	 * Move the libraries of the given selection up.
	 * @param selection the current viewer selection
	 */
	public void up(IStructuredSelection selection) {
		Set<Object> libraries= getSelectedLibraries(selection);
		for (int i= 0; i < fLibraries.length - 1; i++) {
			if (libraries.contains(fLibraries[i + 1])) {
				LibraryStandin temp= fLibraries[i];
				fLibraries[i]= fLibraries[i + 1];
				fLibraries[i + 1]= temp;
			}
		}
		fViewer.refresh();
		fViewer.setSelection(selection);
	}

	/**
	 * Move the libraries of the given selection down.
	 * @param selection the current viewer selection
	 */
	public void down(IStructuredSelection selection) {
		Set<Object> libraries= getSelectedLibraries(selection);
		for (int i= fLibraries.length - 1; i > 0; i--) {
			if (libraries.contains(fLibraries[i - 1])) {
				LibraryStandin temp= fLibraries[i];
				fLibraries[i]= fLibraries[i - 1];
				fLibraries[i - 1]= temp;
			}
		}
		fViewer.refresh();
		fViewer.setSelection(selection);
	}

	/**
	 * Remove the libraries contained in the given selection.
	 * @param selection the current viewer selection
	 */
	public void remove(IStructuredSelection selection) {
		List<LibraryStandin> newLibraries = new ArrayList<>();
		for (int i = 0; i < fLibraries.length; i++) {
			newLibraries.add(fLibraries[i]);
		}
		Iterator<?> iterator = selection.iterator();
		while (iterator.hasNext()) {
			Object element = iterator.next();
			if (element instanceof LibraryStandin) {
				newLibraries.remove(element);
			} else {
				SubElement subElement = (SubElement)element;
				subElement.remove();
			}
		}
		fLibraries= newLibraries.toArray(new LibraryStandin[newLibraries.size()]);
		fViewer.refresh();
	}

	/**
	 * Add the given libraries before the selection, or after the existing libraries
	 * if the selection is empty.
	 * @param libs the array of <code>LibraryLocation</code>s to add
	 * @param selection the selection to add the new libraries before in the list, or after if the selection
	 * is empty.
	 */
	public void add(LibraryLocation[] libs, IStructuredSelection selection) {
		List<LibraryStandin> newLibraries = new ArrayList<>(fLibraries.length + libs.length);
		for (int i = 0; i < fLibraries.length; i++) {
			newLibraries.add(fLibraries[i]);
		}
		List<LibraryStandin> toAdd = new ArrayList<>(libs.length);
		for (int i = 0; i < libs.length; i++) {
			toAdd.add(new LibraryStandin(libs[i]));
		}
		if (selection.isEmpty()) {
			newLibraries.addAll(toAdd);
		} else {
			Object element= selection.getFirstElement();
			LibraryStandin firstLib;
			if (element instanceof LibraryStandin) {
				firstLib= (LibraryStandin) element;
			} else {
				firstLib= ((SubElement) element).getParent();
			}
			int index = newLibraries.indexOf(firstLib);
			newLibraries.addAll(index, toAdd);
		}
		fLibraries= newLibraries.toArray(new LibraryStandin[newLibraries.size()]);
		fViewer.refresh();
		fViewer.setSelection(new StructuredSelection(libs), true);
	}

	/**
	 * Set the given URL as the javadoc location for the libraries contained in
	 * the given selection.
	 * @param javadocLocation the new java doc location to set
	 * @param selection the selection of libraries to set the new javadoc location for
	 */
	public void setJavadoc(URL javadocLocation, IStructuredSelection selection) {
		Set<Object> libraries= getSelectedLibraries(selection);
		Iterator<Object> iterator = libraries.iterator();
		while (iterator.hasNext()) {
			LibraryStandin standin = (LibraryStandin) iterator.next();
			standin.setJavadocLocation(javadocLocation);
		}
		fViewer.refresh();
	}

	/**
	 * Set the given paths as the source info for the libraries contained in
	 * the given selection.
	 * @param sourceAttachmentPath the path of the new attachment
	 * @param sourceAttachmentRootPath the root path of the new attachment
	 * @param selection the selection of libraries to set the new paths in
	 */
	public void setSourcePath(IPath sourceAttachmentPath, IPath sourceAttachmentRootPath, IStructuredSelection selection) {
		Set<Object> libraries= getSelectedLibraries(selection);
		if (sourceAttachmentPath == null) {
			sourceAttachmentPath = Path.EMPTY;
		}
		if (sourceAttachmentRootPath == null) {
			sourceAttachmentRootPath = Path.EMPTY;
		}
		Iterator<Object> iterator = libraries.iterator();
		while (iterator.hasNext()) {
			LibraryStandin standin = (LibraryStandin) iterator.next();
			standin.setSystemLibrarySourcePath(sourceAttachmentPath);
			standin.setPackageRootPath(sourceAttachmentRootPath);
		}
		fViewer.refresh();
	}

	/**
	 * Set the given paths as the annotations path for the libraries contained in the given selection.
	 *
	 * @param annotationsAttachmentPath
	 *            the path of the new attachment
	 * @param annotationsAttachmentRootPath
	 *            the root path of the new attachment
	 * @param selection
	 *            the selection of libraries to set the new paths in
	 */
	public void setAnnotationsPath(IPath annotationsAttachmentPath, IStructuredSelection selection) {
		Set<Object> libraries = getSelectedLibraries(selection);
		if (annotationsAttachmentPath == null) {
			annotationsAttachmentPath = Path.EMPTY;
		}
		Iterator<Object> iterator = libraries.iterator();
		while (iterator.hasNext()) {
			LibraryStandin standin = (LibraryStandin) iterator.next();
			standin.setExternalAnnotationsPath(annotationsAttachmentPath);
		}
		fViewer.refresh();
	}

	/**
	 * Returns the stand-in libraries being edited.
	 *
	 * @return stand-ins
	 */
	LibraryStandin[] getStandins() {
		return fLibraries;
	}
}
