/*******************************************************************************
 * Copyright (c) 2008, 2016 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.osgi.internal.serviceregistry;

import java.util.*;

/**
 * A Shrinkable Collection. This class provides a wrapper for a list of collections
 * that allows items to be removed from the wrapped collections (shrinking) but
 * does not allow items to be added to the wrapped collections. 
 * 
 * <p>
 * The collections must act as sets in that each collection in the list
 * must not have two entries which are equal.
 * 
 * <p>
 * All the optional <code>Collection</code> operations except
 * <code>add</code> and <code>addAll</code> are supported. Attempting to add to the
 * collection will result in an <code>UnsupportedOperationException</code>.
 *
 */

public class ShrinkableCollection<E> implements Collection<E> {
	private final Collection<? extends E> collection;
	private final List<Collection<? extends E>> list;

	public ShrinkableCollection(Collection<? extends E> c) {
		if (c == null) {
			throw new NullPointerException();
		}
		List<Collection<? extends E>> empty = Collections.<Collection<? extends E>> emptyList();
		list = empty;
		collection = c;
	}

	public ShrinkableCollection(Collection<? extends E> c1, Collection<? extends E> c2) {
		list = new ArrayList<>(2);
		list.add(c1);
		list.add(c2);
		collection = initComposite(list);
	}

	public ShrinkableCollection(List<Collection<? extends E>> l) {
		list = new ArrayList<>(l);
		collection = initComposite(list);
	}

	private static <E> Collection<? extends E> initComposite(List<Collection<? extends E>> collections) {
		int size = 0;
		for (Collection<? extends E> c : collections) {
			assert verifyNoDuplicates(c);
			size += c.size();
		}
		Collection<E> result = new ArrayList<>(size);
		for (Collection<? extends E> c : collections) {
			for (E e : c) {
				if (!result.contains(e)) {
					result.add(e);
				}
			}
		}
		return result;
	}

	private static <E> boolean verifyNoDuplicates(Collection<? extends E> c) {
		for (E e : c) {
			int count = 0;
			for (E f : c) {
				if (e == null) {
					if (f == null) {
						count++;
					}
				} else {
					if (e.equals(f)) {
						count++;
					}
				}
			}
			if (count != 1) {
				return false;
			}
		}
		return true;
	}

	public boolean add(E e) {
		throw new UnsupportedOperationException();
	}

	public boolean addAll(Collection<? extends E> c) {
		throw new UnsupportedOperationException();
	}

	public void clear() {
		collection.clear();
		for (Collection<? extends E> c : list) {
			c.clear();
		}
	}

	public boolean contains(Object o) {
		return collection.contains(o);
	}

	public boolean containsAll(Collection<?> c) {
		return collection.containsAll(c);
	}

	public boolean isEmpty() {
		return collection.isEmpty();
	}

	public Iterator<E> iterator() {
		@SuppressWarnings("unchecked")
		final Iterator<E> iter = (Iterator<E>) collection.iterator();
		final List<Collection<? extends E>> collections = list;
		if (collections.isEmpty()) {
			return iter;
		}
		return new Iterator<E>() {
			private E last;

			public boolean hasNext() {
				return iter.hasNext();
			}

			public E next() {
				last = iter.next();
				return last;
			}

			public void remove() {
				iter.remove();
				for (Collection<? extends E> c : collections) {
					c.remove(last);
				}
			}
		};
	}

	public boolean remove(Object o) {
		final boolean result = collection.remove(o);
		if (result) {
			for (Collection<? extends E> c : list) {
				c.remove(o);
			}
		}
		return result;
	}

	public boolean removeAll(Collection<?> c) {
		final boolean result = collection.removeAll(c);
		if (result) {
			for (Collection<? extends E> cc : list) {
				cc.removeAll(c);
			}
		}
		return result;
	}

	public boolean retainAll(Collection<?> c) {
		final boolean result = collection.retainAll(c);
		if (result) {
			for (Collection<? extends E> cc : list) {
				cc.retainAll(c);
			}
		}
		return result;
	}

	public int size() {
		return collection.size();
	}

	public Object[] toArray() {
		return collection.toArray();
	}

	public <T> T[] toArray(T[] var0) {
		return collection.toArray(var0);
	}

	public String toString() {
		return collection.toString();
	}
}
