/*******************************************************************************
 * Copyright (c) 2005, 2015 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.utility.internal.collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;
import java.util.RandomAccess;
import org.eclipse.jpt.common.utility.internal.Range;
import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
import org.eclipse.jpt.common.utility.internal.iterator.IteratorTools;
import org.eclipse.jpt.common.utility.iterable.ListIterable;
import org.eclipse.jpt.common.utility.predicate.Predicate;
import org.eclipse.jpt.common.utility.transformer.Transformer;

/**
 * {@link List} utility methods.
 */
public final class ListTools {

	// ********** add all **********

	/**
	 * Add all the elements returned by the specified iterable
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 */
	public static <E> boolean addAll(List<? super E> list, int index, Iterable<? extends E> iterable) {
		return addAll(list, index, iterable.iterator());
	}

	/**
	 * Add all the elements returned by the specified iterable
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 * The specified iterable size is a performance hint.
	 */
	public static <E> boolean addAll(List<? super E> list, int index, Iterable<? extends E> iterable, int iterableSize) {
		return addAll(list, index, iterable.iterator(), iterableSize);
	}

	/**
	 * Add all the elements returned by the specified iterator
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 */
	public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator) {
		return iterator.hasNext() && addAll_(list, index, iterator);
	}

	/**
	 * assume the iterator is not empty
	 */
	private static <E> boolean addAll_(List<? super E> list, int index, Iterator<? extends E> iterator) {
		return (index == list.size()) ? CollectionTools.addAll_(list, iterator) : list.addAll(index, arrayList(iterator));
	}

	/**
	 * Add all the elements returned by the specified iterator
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 * The specified iterator size is a performance hint.
	 */
	public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator, int iteratorSize) {
		return iterator.hasNext() && list.addAll(index, arrayList(iterator, iteratorSize));
	}

	/**
	 * Add all the elements in the specified array
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 */
	public static <E> boolean addAll(List<? super E> list, int index, E... array) {
		return (array.length != 0) && list.addAll(index, Arrays.asList(array));
	}


	// ********** diff **********

	/**
	 * Return the range of elements in the specified
	 * arrays that are different.
	 * Return <code>null</code> if the arrays are identical.
	 * Use the elements' {@link Object#equals(Object)} method to compare the
	 * elements.
	 * @see #indexOfDifference(List, List)
	 * @see #lastIndexOfDifference(List, List)
	 */
	public static Range differenceRange(List<?> list1, List<?> list2) {
		int end = lastIndexOfDifference(list1, list2);
		return (end == -1) ? null : new Range(indexOfDifference(list1, list2), end);
	}

	/**
	 * Return the index of the first elements in the specified
	 * lists that are different. If the lists are identical, return
	 * the size of the two lists (i.e. one past the last index).
	 * If the lists are different sizes and all the elements in
	 * the shorter list match their corresponding elements in
	 * the longer list, return the size of the shorter list
	 * (i.e. one past the last index of the shorter list).
	 * Use the elements' {@link Object#equals(Object)} method to compare the
	 * elements.
	 */
	public static int indexOfDifference(List<?> list1, List<?> list2) {
		int end = Math.min(list1.size(), list2.size());
		for (int i = 0; i < end; i++) {
			Object o = list1.get(i);
			if (o == null) {
				if (list2.get(i) != null) {
					return i;
				}
			} else {
				if ( ! o.equals(list2.get(i))) {
					return i;
				}
			}
		}
		return end;
	}

	/**
	 * Return the index of the first elements in the specified
	 * lists that are different, beginning at the end.
	 * If the lists are identical, return -1.
	 * If the lists are different sizes, return the index of the
	 * last element in the longer list.
	 * Use the elements' {@link Object#equals(Object)} method to compare the
	 * elements.
	 */
	public static int lastIndexOfDifference(List<?> list1, List<?> list2) {
		int len1 = list1.size();
		int len2 = list2.size();
		if (len1 != len2) {
			return Math.max(len1, len2) - 1;
		}
		for (int i = len1 - 1; i > -1; i--) {
			Object o = list1.get(i);
			if (o == null) {
				if (list2.get(i) != null) {
					return i;
				}
			} else {
				if ( ! o.equals(list2.get(i))) {
					return i;
				}
			}
		}
		return -1;
	}


	// ********** filter **********

	/**
	 * Return a new list with the filtered
	 * elements of the specified list.
	 */
	public static <E> ArrayList<E> filter(Collection<? extends E> list, Predicate<? super E> predicate) {
		ArrayList<E> result = new ArrayList<E>(list.size());
		for (E each : list) {
			if (predicate.evaluate(each)) {
				result.add(each);
			}
		}
		return result;
	}


	// ********** identity diff **********

	/**
	 * Return the range of elements in the specified
	 * arrays that are different.
	 * Return <code>null</code> if the arrays are identical.
	 * Use object identity to compare the elements.
	 * @see #indexOfIdentityDifference(List, List)
	 * @see #lastIndexOfIdentityDifference(List, List)
	 */
	public static Range identityDifferenceRange(List<?> list1, List<?> list2) {
		int end = lastIndexOfIdentityDifference(list1, list2);
		return (end == -1) ? null : new Range(indexOfIdentityDifference(list1, list2), end);
	}

	/**
	 * Return the index of the first elements in the specified
	 * lists that are different. If the lists are identical, return
	 * the size of the two lists (i.e. one past the last index).
	 * If the lists are different sizes and all the elements in
	 * the shorter list match their corresponding elements in
	 * the longer list, return the size of the shorter list
	 * (i.e. one past the last index of the shorter list).
	 * Use object identity to compare the elements.
	 */
	public static int indexOfIdentityDifference(List<?> list1, List<?> list2) {
		int end = Math.min(list1.size(), list2.size());
		for (int i = 0; i < end; i++) {
			if (list1.get(i) != list2.get(i)) {
				return i;
			}
		}
		return end;
	}

	/**
	 * Return the index of the first elements in the specified
	 * lists that are different, beginning at the end.
	 * If the lists are identical, return -1.
	 * If the lists are different sizes, return the index of the
	 * last element in the longer list.
	 * Use object identity to compare the elements.
	 */
	public static int lastIndexOfIdentityDifference(List<?> list1, List<?> list2) {
		int len1 = list1.size();
		int len2 = list2.size();
		if (len1 != len2) {
			return Math.max(len1, len2) - 1;
		}
		for (int i = len1 - 1; i > -1; i--) {
			if (list1.get(i) != list2.get(i)) {
				return i;
			}
		}
		return -1;
	}


	// ********** index of **********

	/**
	 * Return the index of the first occurrence of the
	 * specified element in the specified list, starting at the specified index;
	 * or return -1 if there is no such element.
	 */
	public static <E> int indexOf(List<E> list, Object value, int startIndex) {
		int size = list.size();
		return (size == 0) ? -1 : (startIndex >= size) ? -1 : indexOf(list, value, (startIndex < 0) ? 0 : startIndex, size);
	}

	/**
	 * assume 0 <= start index < list size
	 */
	private static <E> int indexOf(List<E> list, Object value, int startIndex, int listSize) {
		if (value == null) {
			for (int i = startIndex; i < listSize; i++) {
				if (list.get(i) == null) {
					return i;
				}
			}
		} else {
			for (int i = startIndex; i < listSize; i++) {
				if (value.equals(list.get(i))) {
					return i;
				}
			}
		}
		return -1;
	}

	/**
	 * Return the index of the first occurrence of the
	 * specified element in the specified list, starting at the specified index;
	 * or return -1 if there is no such element.
	 */
	public static <E> int identityIndexOf(List<E> list, Object value, int startIndex) {
		int size = list.size();
		return (size == 0) ? -1 : (startIndex >= size) ? -1 : identityIndexOf(list, value, (startIndex < 0) ? 0 : startIndex, size);
	}

	/**
	 * assume 0 <= start index < list size
	 */
	private static <E> int identityIndexOf(List<E> list, Object value, int startIndex, int listSize) {
		for (int i = startIndex; i < listSize; i++) {
			if (list.get(i) == value) {
				return i;
			}
		}
		return -1;
	}


	// ********** insertion index **********

	/**
	 * Return an index of where the specified comparable object
	 * can be inserted into the specified sorted list and still keep
	 * the list sorted. If the specified sorted list is an instance of
	 * {@link RandomAccess} return the <em>maximum</em> insertion index;
	 * otherwise return the <em>minimum</em> insertion index.
	 */
	public static <E extends Comparable<? super E>> int insertionIndexOf(List<E> sortedList, Comparable<E> value) {
		if (sortedList instanceof RandomAccess) {
			for (int i = sortedList.size(); i-- > 0; ) {
				if (value.compareTo(sortedList.get(i)) >= 0) {
					return i + 1;
				}
			}
			return 0;
		}
		int i = 0;
		for (E element : sortedList) {
			if (value.compareTo(element) <= 0) {
				return i;
			}
			i++;
		}
		return i;
	}

	/**
	 * Return an index of where the specified comparable object
	 * can be inserted into the specified sorted list and still keep
	 * the list sorted. If the specified sorted list is an instance of
	 * {@link RandomAccess} return the <em>maximum</em> insertion index;
	 * otherwise return the <em>minimum</em> insertion index.
	 */
	public static <E> int insertionIndexOf(List<E> sortedList, E value, Comparator<? super E> comparator) {
		if (sortedList instanceof RandomAccess) {
			for (int i = sortedList.size(); i-- > 0; ) {
				if (comparator.compare(value, sortedList.get(i)) >= 0) {
					return i + 1;
				}
			}
			return 0;
		}
		int i = 0;
		for (E element : sortedList) {
			if (comparator.compare(value, element) <= 0) {
				return i;
			}
			i++;
		}
		return i;
	}


	// ********** last index of **********

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified array, starting at the specified index;
	 * or return -1 if there is no such element.
	 */
	public static <E> int lastIndexOf(List<E> list, Object value, int startIndex) {
		if (startIndex < 0) {
			return -1;
		}
		int size = list.size();
		return (size == 0) ? -1 : lastIndexOf_(list, value, (startIndex >= size) ? size - 1 : startIndex);
	}

	/**
	 * assume 0 <= start index < list size
	 */
	private static <E> int lastIndexOf_(List<E> list, Object value, int startIndex) {
		if (value == null) {
			for (int i = startIndex; i >= 0; i--) {
				if (list.get(i) == null) {
					return i;
				}
			}
		} else {
			for (int i = startIndex; i >= 0; i--) {
				if (value.equals(list.get(i))) {
					return i;
				}
			}
		}
		return -1;
	}

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified array, starting at the specified index;
	 * or return -1 if there is no such element.
	 */
	public static <E> int lastIdentityIndexOf(List<E> list, Object value, int startIndex) {
		if (startIndex < 0) {
			return -1;
		}
		int size = list.size();
		return (size == 0) ? -1 : lastIdentityIndexOf_(list, value, (startIndex >= size) ? size - 1 : startIndex);
	}

	/**
	 * assume 0 <= start index < list size
	 */
	private static <E> int lastIdentityIndexOf_(List<E> list, Object value, int startIndex) {
		for (int i = startIndex; i >= 0; i--) {
			if (list.get(i) == value) {
				return i;
			}
		}
		return -1;
	}


	// ********** move **********

	/**
	 * Move the specified element from its current position to the specified
	 * index. Return the altered list.
	 */
	public static <E, L extends List<E>> L move(L list, int index, E element) {
		return move(list, index, list.indexOf(element));
	}

	/**
	 * Move an element from the specified source index to the specified target
	 * index. Return the altered list.
	 */
	public static <E, L extends List<E>> L move(L list, int targetIndex, int sourceIndex) {
		return (targetIndex == sourceIndex) ? list : move_(list, targetIndex, sourceIndex);
	}

	/**
	 * assume targetIndex != sourceIndex
	 */
	private static <E, L extends List<E>> L move_(L list, int targetIndex, int sourceIndex) {
		if (list instanceof RandomAccess) {
			// move elements, leaving the list in place
			E temp = list.get(sourceIndex);
			if (targetIndex < sourceIndex) {
				for (int i = sourceIndex; i-- > targetIndex; ) {
					list.set(i + 1, list.get(i));
				}
			} else {
				for (int i = sourceIndex; i < targetIndex; i++) {
					list.set(i, list.get(i + 1));
				}
			}
			list.set(targetIndex, temp);
		} else {
			// remove the element and re-add it at the target index
			list.add(targetIndex, list.remove(sourceIndex));
		}
		return list;
	}

	/**
	 * Move elements from the specified source index to the specified target
	 * index. Return the altered list.
	 */
	public static <E, L extends List<E>> L move(L list, int targetIndex, int sourceIndex, int length) {
		if ((targetIndex == sourceIndex) || (length == 0)) {
			return list;
		}
		if (length == 1) {
			return move_(list, targetIndex, sourceIndex);
		}
		if (list instanceof RandomAccess) {
			// move elements, leaving the list in place
			ArrayList<E> temp = new ArrayList<E>(list.subList(sourceIndex, sourceIndex + length));
			if (targetIndex < sourceIndex) {
				for (int i = sourceIndex; i-- > targetIndex; ) {
					list.set(i + length, list.get(i));
				}
			} else {
				for (int i = sourceIndex; i < targetIndex; i++) {
					list.set(i, list.get(i + length));
				}
			}
			for (int i = 0; i < length; i++) {
				list.set(targetIndex + i, temp.get(i));
			}
		} else {
			// remove the elements and re-add them at the target index
			list.addAll(targetIndex, removeElementsAtIndex(list, sourceIndex, length));
		}
		return list;
	}


	// ********** remove **********

	/**
	 * Remove the elements at the specified index.
	 * Return the removed elements.
	 */
	public static <E> ArrayList<E> removeElementsAtIndex(List<? extends E> list, int index, int length) {
		List<? extends E> subList = list.subList(index, index + length);
		ArrayList<E> removed = new ArrayList<E>(subList);
		subList.clear();
		return removed;
	}

	/**
	 * Remove any duplicate elements from the specified list,
	 * while maintaining the order.
	 * Return whether the list changed as a result.
	 */
	public static <E> boolean removeDuplicateElements(List<E> list) {
		int listSize = list.size();
		if ((listSize == 0) || (listSize == 1)) {
			return false;
		}

		LinkedHashSet<E> temp = new LinkedHashSet<E>(listSize);		// take advantage of hashed look-up
		boolean modified = false;
		for (E item : list) {
			if ( ! temp.add(item)) {
				modified = true;  // duplicate item
			}
		}
		if (modified) {
			int i = 0;
			for (E e : temp) {
				list.set(i, e);
				i++;
			}
			int tempSize = temp.size();
			for (i = list.size(); i-- > tempSize; ) {
				list.remove(i);  // pull off the end
			}
		}
		return modified;
	}


	// ********** rotate **********

	/**
	 * Return the list after it has been "rotated" by one position.
	 */
	public static <E> List<E> rotate(List<E> list) {
		return rotate(list, 1);
	}


	// ********** transform **********

	/**
	 * Return a new list with transformations of the
	 * elements in the specified list.
	 */
	public static <I, O> ArrayList<O> transform(Collection<I> list, Transformer<? super I, ? extends O> transformer) {
		ArrayList<O> result = new ArrayList<O>(list.size());
		for (I each : list) {
			result.add(transformer.transform(each));
		}
		return result;
	}


	// ********** java.util.Collections enhancements **********

	/**
	 * Return the destination list after the source list has been copied into it.
	 * @see Collections#copy(List, List)
	 */
	public static <E, L extends List<E>> L copy(L dest, List<? extends E> src) {
		Collections.copy(dest, src);
		return dest;
	}

	/**
	 * Return the list after it has been "filled".
	 * @see Collections#fill(List, Object)
	 */
	public static <E, L extends List<E>> L fill(L list, E value) {
		Collections.fill(list, value);
		return list;
	}

	/**
	 * Return the list after it has been "reversed".
	 * @see Collections#reverse(List)
	 */
	public static <E, L extends List<E>> L reverse(L list) {
		Collections.reverse(list);
		return list;
	}

	/**
	 * Return the list after it has been "rotated".
	 * @see Collections#rotate(List, int)
	 */
	public static <E, L extends List<E>> L rotate(L list, int distance) {
		Collections.rotate(list, distance);
		return list;
	}

	/**
	 * Return the list after it has been "shuffled".
	 * @see Collections#shuffle(List)
	 */
	public static <E, L extends List<E>> L shuffle(L list) {
		Collections.shuffle(list);
		return list;
	}

	/**
	 * Return the list after it has been "shuffled".
	 * @see Collections#shuffle(List, Random)
	 */
	public static <E, L extends List<E>> L shuffle(L list, Random random) {
		Collections.shuffle(list, random);
		return list;
	}

	/**
	 * Return the list after it has been "sorted".
	 * NB: The list is sorted in place as a side-effect.
	 * @see Collections#sort(List)
	 */
	public static <E extends Comparable<? super E>, L extends List<E>> L sort(L list) {
		Collections.sort(list);
		return list;
	}

	/**
	 * Return the list after it has been "sorted".
	 * NB: The list is sorted in place as a side-effect.
	 * @see Collections#sort(List, Comparator)
	 */
	public static <E, L extends List<E>> L sort(L list, Comparator<? super E> comparator) {
		Collections.sort(list, comparator);
		return list;
	}

	/**
	 * Return the list after the specified elements have been "swapped".
	 * @see Collections#swap(List, int, int)
	 */
	public static <E, L extends List<E>> L swap(L list, int i, int j) {
		Collections.swap(list, i, j);
		return list;
	}


	// ********** factory methods **********

	/**
	 * Return an array list corresponding to the specified iterable.
	 */
	public static <E> ArrayList<E> arrayList(Iterable<? extends E> iterable) {
		return arrayList(iterable.iterator());
	}

	/**
	 * Return an array list corresponding to the specified iterable.
	 * The specified iterable size is a performance hint.
	 */
	public static <E> ArrayList<E> arrayList(Iterable<? extends E> iterable, int iterableSize) {
		return arrayList(iterable.iterator(), iterableSize);
	}

	/**
	 * Return an array list corresponding to the specified iterator.
	 */
	public static <E> ArrayList<E> arrayList(Iterator<? extends E> iterator) {
		return arrayList(iterator, new ArrayList<E>());
	}

	/**
	 * Return an array list corresponding to the specified iterator.
	 * The specified iterator size is a performance hint.
	 */
	public static <E> ArrayList<E> arrayList(Iterator<? extends E> iterator, int iteratorSize) {
		return arrayList(iterator, new ArrayList<E>(iteratorSize));
	}

	private static <E> ArrayList<E> arrayList(Iterator<? extends E> iterator, ArrayList<E> list) {
		while (iterator.hasNext()) {
			list.add(iterator.next());
		}
		return list;
	}

	/**
	 * Return an array list corresponding to the specified array.
	 * Unlike {@link Arrays#asList(Object[])}, the list
	 * is modifiable and is not backed by the array.
	 */
	public static <E> ArrayList<E> arrayList(E... array) {
		ArrayList<E> list = new ArrayList<E>(array.length);
		for (E e : array) {
			list.add(e);
		}
		return list;
	}


	// ********** transformers **********

	/**
	 * Return a transformer that transforms a {@link List} into a
	 * {@link ListIterator}.
	 */
	@SuppressWarnings("unchecked")
	public static <E> Transformer<List<E>, ListIterator<E>> listIteratorTransformer() {
		return LIST_ITERATOR_TRANSFORMER;
	}

	/**
	 * A transformer that transforms a {@link List} into a
	 * {@link ListIterator}.
	 */
	@SuppressWarnings("rawtypes")
	public static final Transformer LIST_ITERATOR_TRANSFORMER = new ListIteratorTransformer();

	/**
	 * A transformer that transforms a {@link List} into a
	 * {@link ListIterator}.
	 */
	public static class ListIteratorTransformer<E>
		implements Transformer<List<E>, ListIterator<E>>
	{
		public ListIterator<E> transform(List<E> list) {
			return list.listIterator();
		}
		@Override
		public String toString() {
			return this.getClass().getSimpleName();
		}
	}

	/**
	 * Return a transformer that transforms a {@link List} into a
	 * <em>read-only</em> {@link ListIterator}.
	 */
	@SuppressWarnings("unchecked")
	public static <E> Transformer<List<? extends E>, ListIterator<E>> readOnlyListIteratorTransformer() {
		return READ_ONLY_LIST_ITERATOR_TRANSFORMER;
	}

	/**
	 * A transformer that transforms a {@link List} into a
	 * <em>read-only</em> {@link ListIterator}.
	 */
	@SuppressWarnings("rawtypes")
	public static final Transformer READ_ONLY_LIST_ITERATOR_TRANSFORMER = new ReadOnlyListIteratorTransformer();

	/**
	 * A transformer that transforms a {@link List} into a
	 * <em>read-only</em> {@link ListIterator}.
	 */
	public static class ReadOnlyListIteratorTransformer<E>
		implements Transformer<List<? extends E>, ListIterator<E>>
	{
		public ListIterator<E> transform(List<? extends E> list) {
			return IteratorTools.<E>readOnly(list.listIterator());
		}
		@Override
		public String toString() {
			return this.getClass().getSimpleName();
		}
	}

	/**
	 * Return a transformer that transforms a {@link List} into a
	 * {@link ListIterable}.
	 */
	@SuppressWarnings("unchecked")
	public static <E> Transformer<List<E>, ListIterable<E>> listIterableTransformer() {
		return LIST_ITERABLE_TRANSFORMER;
	}

	/**
	 * A transformer that transforms a {@link List} into a
	 * {@link ListIterable}.
	 */
	@SuppressWarnings("rawtypes")
	public static final Transformer LIST_ITERABLE_TRANSFORMER = new ListIterableTransformer();

	/**
	 * A transformer that transforms a {@link List} into a
	 * {@link ListIterable}.
	 */
	public static class ListIterableTransformer<E>
		implements Transformer<List<E>, ListIterable<E>>
	{
		public ListIterable<E> transform(List<E> list) {
			return IterableTools.listIterable(list);
		}
		@Override
		public String toString() {
			return this.getClass().getSimpleName();
		}
	}

	/**
	 * Return a transformer that transforms a {@link List} into a
	 * <em>read-only</em> {@link ListIterable}.
	 */
	@SuppressWarnings("unchecked")
	public static <E> Transformer<List<? extends E>, ListIterable<E>> readOnlyListIterableTransformer() {
		return READ_ONLY_LIST_ITERABLE_TRANSFORMER;
	}

	/**
	 * A transformer that transforms a {@link List} into a
	 * <em>read-only</em> {@link ListIterable}.
	 */
	@SuppressWarnings("rawtypes")
	public static final Transformer READ_ONLY_LIST_ITERABLE_TRANSFORMER = new ReadOnlyListIterableTransformer();

	/**
	 * A transformer that transforms a {@link List} into a
	 * <em>read-only</em> {@link ListIterable}.
	 */
	public static class ReadOnlyListIterableTransformer<E>
		implements Transformer<List<? extends E>, ListIterable<E>>
	{
		public ListIterable<E> transform(List<? extends E> list) {
			return IterableTools.<E>readOnly(IterableTools.listIterable(list));
		}
		@Override
		public String toString() {
			return this.getClass().getSimpleName();
		}
	}


	// ********** constructor **********

	/**
	 * Suppress default constructor, ensuring non-instantiability.
	 */
	private ListTools() {
		super();
		throw new UnsupportedOperationException();
	}
}
