/*=============================================================================#
 # Copyright (c) 2004, 2021 IBM Corporation and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     IBM Corporation - initial API and implementation
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - extended generalized API
 #=============================================================================*/

package org.eclipse.statet.ecommons.collections;

import java.lang.reflect.Array;
import java.util.Arrays;


/**
 * ListenerList for common usage with support of generics.
 * 
 * This class is a thread safe list that is designed for storing lists of items.
 * The implementation is optimized for minimal memory footprint, frequent reads
 * and infrequent writes.  Modification of the list is synchronized and relatively
 * expensive, while accessing the items is very fast.  Readers are given access
 * to the underlying array data structure for reading, with the trust that they will
 * not modify the underlying array.
 * <p>
 * <a name="same">A item list handles the <i>same</i> item being added
 * multiple times, and tolerates removal of items that are the same as other
 * items in the list.  For this purpose, items can be compared with each other
 * using either equality or identity, as specified in the list constructor.
 * </p>
 * <p>
 * Use the <code>getListeners</code> method when notifying items. The recommended
 * code sequence for notifying all registered items of say,
 * <code>FooListener.eventHappened</code>, is:
 * 
 * <pre>
 * Object[] listeners = myListenerList.toArray();
 * for (int i = 0; i &lt; listeners.length; ++i) {
 *     ((FooListener) listeners[i]).eventHappened(event);
 * }
 * </pre>
 * 
 * </p><p>
 * This class can be used without OSGi running.
 * </p>
 * 
 * @deprecated
 */
@Deprecated
public final class FastList<T> {
	
	/**
	 * Mode constant (value 0) indicating that items should be considered
	 * the <a href="#same">same</a> if they are equal.
	 */
	public static final int EQUALITY = 0;
	
	/**
	 * Mode constant (value 1) indicating that items should be considered
	 * the <a href="#same">same</a> if they are identical.
	 */
	public static final int IDENTITY = 1;
	
	
	/**
	 * Indicates the comparison mode used to determine if two
	 * items are equivalent
	 */
	private final boolean identity;
	
	private final Class<T> type;
	private final T[] emptyArray;
	
	/**
	 * The list of items.  Initially empty but initialized
	 * to an array of size capacity the first time a item is added.
	 * Maintains invariant: items != null
	 */
	private volatile T[] items;
	
	
	/**
	 * Creates a item list in which items are compared using equality.
	 */
	public FastList(final Class<T> type) {
		this(type, EQUALITY, null);
	}
	
	/**
	 * Creates a item list using the provided comparison mode.
	 * 
	 * @param mode The mode used to determine if items are the <a href="#same">same</a>.
	 */
	public FastList(final Class<T> type, final int mode) {
		this(type, mode, null);
	}
	
	/**
	 * Creates a item list using the provided comparison mode
	 * and initial items.
	 * 
	 * @param mode The mode used to determine if items are the <a href="#same">same</a>
	 * @param initial array with the initial items, the array is used directly
	 */
	public FastList(final Class<T> type, final int mode, final T[] initial) {
		if (mode != EQUALITY && mode != IDENTITY) {
			throw new IllegalArgumentException();
		}
		this.type = type;
		this.identity = mode == IDENTITY;
		
		emptyArray = (T[]) Array.newInstance(type, 0);
		items = (initial != null) ? initial : emptyArray;
	}
	
	
	/**
	 * Adds a item to this list. This method has no effect if the <a href="#same">same</a>
	 * item is already registered.
	 * 
	 * @param item the non-<code>null</code> item to add
	 */
	public synchronized void add(final T item) {
		// This method is synchronized to protect against multiple threads adding
		// or removing items concurrently. This does not block concurrent readers.
		if (item == null) {
			throw new IllegalArgumentException();
		}
		// check for duplicates
		final int oldSize = items.length;
		for (int i = 0; i < oldSize; ++i) {
			final Object item2 = items[i];
			if (identity ? item == item2 : item.equals(item2)) {
				return;
			}
		}
		// Thread safety: create new array to avoid affecting concurrent readers
		final T[] newListeners = (T[]) Array.newInstance(type, oldSize + 1);
		System.arraycopy(items, 0, newListeners, 0, oldSize);
		newListeners[oldSize] = item;
		//atomic assignment
		this.items = newListeners;
	}
	
	/**
	 * Returns an array containing all the registered items.
	 * The resulting array is unaffected by subsequent adds or removes.
	 * If there are no items registered, the result is an empty array.
	 * Use this method when notifying items, so that any modifications
	 * to the item list during the notification will have no effect on
	 * the notification itself.
	 * <p>
	 * Note: Callers of this method <b>must not</b> modify the returned array.
	 * 
	 * @return the list of registered items
	 */
	public T[] toArray() {
		return items;
	}
	
	/**
	 * Returns whether this item list is empty.
	 * 
	 * @return <code>true</code> if there are no registered items, and
	 *   <code>false</code> otherwise
	 */
	public boolean isEmpty() {
		return items.length == 0;
	}
	
	/**
	 * Removes a item from this list. Has no effect if the <a href="#same">same</a>
	 * item was not already registered.
	 * 
	 * @param item the non-<code>null</code> item to remove
	 */
	public synchronized void remove(final T item) {
		// This method is synchronized to protect against multiple threads adding
		// or removing items concurrently. This does not block concurrent readers.
		if (item == null) {
			throw new IllegalArgumentException();
		}
		final int oldSize = items.length;
		for (int i = 0; i < oldSize; ++i) {
			final Object item2 = items[i];
			if (identity ? item == item2 : item.equals(item2)) {
				if (oldSize == 1) {
					items = emptyArray;
				} else {
					// Thread safety: create new array to avoid affecting concurrent readers
					final T[] newListeners = (T[]) Array.newInstance(type, oldSize - 1);
					System.arraycopy(items, 0, newListeners, 0, i);
					System.arraycopy(items, i + 1, newListeners, i, oldSize - i - 1);
					//atomic assignment to field
					this.items = newListeners;
				}
				return;
			}
		}
	}
	
	/**
	 * Replaces an item from this list with a new item. If the old item is not in the list,
	 * the new item is added to the list.
	 * 
	 * @param oldItem the item to replace
	 * @param newItem the non-<code>null</code> item to add
	 */
	public synchronized void replace(final T oldItem, final T newItem) {
		// This method is synchronized to protect against multiple threads adding
		// or removing items concurrently. This does not block concurrent readers.
		if (newItem == null) {
			throw new IllegalArgumentException();
		}
		int remove = -1;
		final int oldSize = items.length;
		if (oldItem != null) {
			if (identity ? oldItem != newItem : !oldItem.equals(newItem)) {
				for (int i = 0; i < oldSize; ++i) {
					final Object item2 = items[i];
					if (identity ? newItem == item2 : newItem.equals(item2)) {
						remove = i;
						break;
					}
				}
			}
			for (int i = 0; i < oldSize; ++i) {
				final Object item2 = items[i];
				if (identity ? oldItem == item2 : oldItem.equals(item2)) {
					// Thread safety: create new array to avoid affecting concurrent readers
					if (remove >= 0 && remove != i) {
						final T[] newListeners = (T[]) Array.newInstance(type, oldSize - 1);
						System.arraycopy(items, 0, newListeners, 0, remove);
						System.arraycopy(items, remove + 1, newListeners, remove, oldSize - remove - 1);
						newListeners[i < remove ? i : (i - 1)] = newItem;
						this.items = newListeners;
					}
					else {
						final T[] newListeners = (T[]) Array.newInstance(type, oldSize);
						System.arraycopy(items, 0, newListeners, 0, oldSize);
						newListeners[i] = newItem;
						this.items = newListeners;
					}
					return;
				}
			}
		}
		if (remove >= 0) {
			final T[] newListeners = (T[]) Array.newInstance(type, oldSize);
			System.arraycopy(items, 0, newListeners, 0, remove);
			System.arraycopy(items, remove + 1, newListeners, remove, oldSize - remove - 1);
			newListeners[oldSize - 1] = newItem;
			this.items = newListeners;
		}
		else {
			final T[] newListeners = (T[]) Array.newInstance(type, oldSize + 1);
			System.arraycopy(items, 0, newListeners, 0, oldSize);
			newListeners[oldSize] = newItem;
			this.items = newListeners;
		}
	}
	
	/**
	 * Returns the number of registered items.
	 * 
	 * @return the number of registered items
	 */
	public int size() {
		return items.length;
	}
	
	/**
	 * Removes all items from this list.
	 * 
	 * @return the previous registered items
	 */
	public synchronized T[] clear() {
		final T[] oldListeners = items;
		items = emptyArray;
		return oldListeners;
	}
	
	
	@Override
	public String toString() {
		return Arrays.toString(items);
	}
	
}
