/*******************************************************************************
 * Copyright (c) 2000, 2019 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:
 *     Peter Shipton - original hashtable implementation
 *     Nick Edgar - added element comparer support
 *     David Saff (saff@mit.edu) - bug 102632: [JUnit] Support for JUnit 4.
 *******************************************************************************/

package org.eclipse.jdt.internal.junit.runner;

import java.util.Enumeration;
import java.util.NoSuchElementException;

/**
 * This is a copy of CustomHashtable from org.eclipse.jface.viewers
 */
/* package */public final class CustomHashtable {

	/**
	 * HashMapEntry is an internal class which is used to hold the entries of a
	 * Hashtable.
	 */
	private static class HashMapEntry {

		Object key, value;

		HashMapEntry next;

		HashMapEntry(Object theKey, Object theValue) {
			key= theKey;
			value= theValue;
		}

		@Override
		public String toString() {
			StringBuffer buffer= new StringBuffer();
			appendToStringWithCommaNL(buffer);
			int length= buffer.length();
			if (length >= 2)
				return buffer.substring(0, length - 2);
			else
				return buffer.toString();
		}

		private void appendToStringWithCommaNL(StringBuffer buffer) {
			CustomHashtable.HashMapEntry hashMapEntry= this;
			do {
				buffer.append(hashMapEntry.key);
				buffer.append('=');
				buffer.append(hashMapEntry.value);
				buffer.append(",\n"); //$NON-NLS-1$
				hashMapEntry= hashMapEntry.next;
			} while (hashMapEntry != null);
		}
	}

	private static final class EmptyEnumerator implements Enumeration<Object> {

		public boolean hasMoreElements() {
			return false;
		}

		public Object nextElement() {
			throw new NoSuchElementException();
		}
	}

	private class HashEnumerator implements Enumeration<Object> {

		boolean key;

		int start;

		HashMapEntry entry;

		HashEnumerator(boolean isKey) {
			key= isKey;
			start= firstSlot;
		}

		public boolean hasMoreElements() {
			if (entry != null)
				return true;
			while (start <= lastSlot)
				if (elementData[start++] != null) {
					entry= elementData[start - 1];
					return true;
				}
			return false;
		}

		public Object nextElement() {
			if (hasMoreElements()) {
				Object result= key ? entry.key : entry.value;
				entry= entry.next;
				return result;
			} else
				throw new NoSuchElementException();
		}
	}

	transient int elementCount;

	transient HashMapEntry[] elementData;

	private float loadFactor;

	private int threshold;

	transient int firstSlot= 0;

	transient int lastSlot= - 1;

	transient private IElementComparer comparer;

	private static final EmptyEnumerator emptyEnumerator= new EmptyEnumerator();

	/**
	 * The default capacity used when not specified in the constructor.
	 */
	public static final int DEFAULT_CAPACITY= 13;

	/**
	 * Constructs a new Hashtable using the default capacity and load factor.
	 */
	public CustomHashtable() {
		this(13);
	}

	/**
	 * Constructs a new Hashtable using the specified capacity and the default
	 * load factor.
	 *
	 * @param capacity the initial capacity
	 */
	public CustomHashtable(int capacity) {
		this(capacity, null);
	}

	/**
	 * Constructs a new hash table with the default capacity and the given
	 * element comparer.
	 *
	 * @param comparer the element comparer to use to compare keys and obtain
	 *        hash codes for keys, or <code>null</code> to use the normal
	 *        <code>equals</code> and <code>hashCode</code> methods
	 */
	public CustomHashtable(IElementComparer comparer) {
		this(DEFAULT_CAPACITY, comparer);
	}

	/**
	 * Constructs a new hash table with the given capacity and the given element
	 * comparer.
	 *
	 * @param capacity the maximum number of elements that can be added without
	 *        rehashing
	 * @param comparer the element comparer to use to compare keys and obtain
	 *        hash codes for keys, or <code>null</code> to use the normal
	 *        <code>equals</code> and <code>hashCode</code> methods
	 */
	public CustomHashtable(int capacity, IElementComparer comparer) {
		if (capacity >= 0) {
			elementCount= 0;
			elementData= new HashMapEntry[capacity == 0 ? 1 : capacity];
			firstSlot= elementData.length;
			loadFactor= 0.75f;
			computeMaxSize();
		} else
			throw new IllegalArgumentException();
		this.comparer= comparer;
	}

	/**
	 * Constructs a new hash table with enough capacity to hold all keys in the
	 * given hash table, then adds all key/value pairs in the given hash table
	 * to the new one, using the given element comparer.
	 *
	 * @param table the original hash table
	 * @param comparer the element comparer to use to compare keys and obtain
	 *        hash codes for keys, or <code>null</code> to use the normal
	 *        <code>equals</code> and <code>hashCode</code> methods
	 */
	public CustomHashtable(CustomHashtable table, IElementComparer comparer) {
		this(table.size() * 2, comparer);
		for (int i= table.elementData.length; --i >= 0;) {
			HashMapEntry entry= table.elementData[i];
			while (entry != null) {
				put(entry.key, entry.value);
				entry= entry.next;
			}
		}
	}

	private void computeMaxSize() {
		threshold= (int) (elementData.length * loadFactor);
	}

	/**
	 * Answers if this Hashtable contains the specified object as a key of one
	 * of the key/value pairs.
	 *
	 * @param key the object to look for as a key in this Hashtable
	 * @return true if object is a key in this Hashtable, false otherwise
	 */
	public boolean containsKey(Object key) {
		return getEntry(key) != null;
	}

	/**
	 * Answers an Enumeration on the values of this Hashtable. The results of
	 * the Enumeration may be affected if the contents of this Hashtable are
	 * modified.
	 *
	 * @return an Enumeration of the values of this Hashtable
	 */
	public Enumeration<?> elements() {
		if (elementCount == 0)
			return emptyEnumerator;
		return new HashEnumerator(false);
	}

	/**
	 * Answers the value associated with the specified key in this Hashtable.
	 *
	 * @param key the key of the value returned
	 * @return the value associated with the specified key, null if the
	 *         specified key does not exist
	 */
	public Object get(Object key) {
		int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
		HashMapEntry entry= elementData[index];
		while (entry != null) {
			if (keyEquals(key, entry.key))
				return entry.value;
			entry= entry.next;
		}
		return null;
	}

	/**
	 * Answers the stored key that is equal to the specified key.
	 *
	 * @param key the key to search
	 * @return the stored key, or null if the specified key does not exist
	 */
	public Object getKey(Object key) {
		int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
		HashMapEntry entry= elementData[index];
		while (entry != null) {
			if (keyEquals(key, entry.key))
				return entry.key;
			entry= entry.next;
		}
		return null;
	}

	private HashMapEntry getEntry(Object key) {
		int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
		HashMapEntry entry= elementData[index];
		while (entry != null) {
			if (keyEquals(key, entry.key))
				return entry;
			entry= entry.next;
		}
		return null;
	}

	/**
	 * Answers the hash code for the given key.
	 *
	 * @param key key
	 * @return hash code for key
	 */
	private int hashCode(Object key) {
		if (comparer == null)
			return key.hashCode();
		else
			return comparer.hashCode(key);
	}

	/**
	 * Compares two keys for equality.
	 *
	 * @param a first key
	 * @param b second key
	 *
	 * @return <code>true</code> iff the keys are deemed equal
	 */
	private boolean keyEquals(Object a, Object b) {
		if (comparer == null)
			return a.equals(b);
		else
			return comparer.equals(a, b);
	}

	/**
	 * Answers an Enumeration on the keys of this Hashtable. The results of the
	 * Enumeration may be affected if the contents of this Hashtable are
	 * modified.
	 *
	 * @return an Enumeration of the keys of this Hashtable
	 */
	public Enumeration<?> keys() {
		if (elementCount == 0)
			return emptyEnumerator;
		return new HashEnumerator(true);
	}

	/**
	 * Associate the specified value with the specified key in this Hashtable.
	 * If the key already exists, the old value is replaced. The key and value
	 * cannot be null.
	 *
	 * @param key the key to add
	 * @param value the value to add
	 * @return the old value associated with the specified key, null if the key
	 *         did not exist
	 */
	public Object put(Object key, Object value) {
		if (key != null && value != null) {
			int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
			HashMapEntry entry= elementData[index];
			while (entry != null && ! keyEquals(key, entry.key))
				entry= entry.next;
			if (entry == null) {
				if (++elementCount > threshold) {
					rehash();
					index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
				}
				if (index < firstSlot)
					firstSlot= index;
				if (index > lastSlot)
					lastSlot= index;
				entry= new HashMapEntry(key, value);
				entry.next= elementData[index];
				elementData[index]= entry;
				return null;
			}
			Object result= entry.value;
			entry.key= key; // important to avoid hanging onto keys that are
							// equal but "old" -- see bug 30607
			entry.value= value;
			return result;
		} else
			throw new NullPointerException();
	}

	/**
	 * Increases the capacity of this Hashtable. This method is sent when the
	 * size of this Hashtable exceeds the load factor.
	 */
	private void rehash() {
		int length= elementData.length << 1;
		if (length == 0)
			length= 1;
		firstSlot= length;
		lastSlot= - 1;
		HashMapEntry[] newData= new HashMapEntry[length];
		for (int i= elementData.length; --i >= 0;) {
			HashMapEntry entry= elementData[i];
			while (entry != null) {
				int index= (hashCode(entry.key) & 0x7FFFFFFF) % length;
				if (index < firstSlot)
					firstSlot= index;
				if (index > lastSlot)
					lastSlot= index;
				HashMapEntry next= entry.next;
				entry.next= newData[index];
				newData[index]= entry;
				entry= next;
			}
		}
		elementData= newData;
		computeMaxSize();
	}

	/**
	 * Remove the key/value pair with the specified key from this Hashtable.
	 *
	 * @param key the key to remove
	 * @return the value associated with the specified key, null if the
	 *         specified key did not exist
	 */
	public Object remove(Object key) {
		HashMapEntry last= null;
		int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
		HashMapEntry entry= elementData[index];
		while (entry != null && ! keyEquals(key, entry.key)) {
			last= entry;
			entry= entry.next;
		}
		if (entry != null) {
			if (last == null)
				elementData[index]= entry.next;
			else
				last.next= entry.next;
			elementCount--;
			return entry.value;
		}
		return null;
	}

	/**
	 * Answers the number of key/value pairs in this Hashtable.
	 *
	 * @return the number of key/value pairs in this Hashtable
	 */
	public int size() {
		return elementCount;
	}

	/**
	 * Answers the string representation of this Hashtable.
	 *
	 * @return the string representation of this Hashtable
	 */
	@Override
	public String toString() {
		if (size() == 0)
			return "{}"; //$NON-NLS-1$

		StringBuffer buffer= new StringBuffer();
		buffer.append('{');
		for (int i= elementData.length; --i >= 0;) {
			HashMapEntry entry= elementData[i];
			if (entry != null)
				entry.appendToStringWithCommaNL(buffer);
		}
		// Remove the last ", "
		if (elementCount > 0)
			buffer.setLength(buffer.length() - 2);
		buffer.append('}');
		return buffer.toString();
	}
}
