/*******************************************************************************
 * Copyright (c) 2003, 2017 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.framework.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleException;

/**
 * Headers classes. This class implements a Dictionary that has
 * the following behavior:
 * <ul>
 * <li>put and remove clear throw UnsupportedOperationException.
 * The Dictionary is thus read-only to others.
 * <li>The String keys in the Dictionary are case-preserved,
 * but the get operation is case-insensitive.
 * </ul>
 * @since 3.1
 * @deprecated As of 3.13. Replaced by {@link CaseInsensitiveDictionaryMap}.
 */
@Deprecated
public class Headers<K, V> extends Dictionary<K, V> implements Map<K, V> {
	private boolean readOnly = false;
	private K[] headers;
	private V[] values;
	private int size = 0;

	/**
	 * Create an empty Headers dictionary.
	 *
	 * @param initialCapacity The initial capacity of this Headers object.
	 */
	public Headers(int initialCapacity) {
		super();
		@SuppressWarnings("unchecked")
		K[] k = (K[]) new Object[initialCapacity];
		headers = k;
		@SuppressWarnings("unchecked")
		V[] v = (V[]) new Object[initialCapacity];
		values = v;
	}

	/**
	 * Create a Headers dictionary from a Dictionary.
	 *
	 * @param values The initial dictionary for this Headers object.
	 * @exception IllegalArgumentException If a case-variant of the key is
	 * in the dictionary parameter.
	 */
	public Headers(Dictionary<? extends K, ? extends V> values) {
		this(values.size());
		/* initialize the headers and values */
		Enumeration<? extends K> keys = values.keys();
		while (keys.hasMoreElements()) {
			K key = keys.nextElement();
			set(key, values.get(key));
		}
	}

	/**
	 * Case-preserved keys.
	 */
	public synchronized Enumeration<K> keys() {
		return new ArrayEnumeration<>(headers, size);
	}

	/**
	 * Values.
	 */
	public synchronized Enumeration<V> elements() {
		return new ArrayEnumeration<>(values, size);
	}

	private int getIndex(Object key) {
		boolean stringKey = key instanceof String;
		for (int i = 0; i < size; i++) {
			if (stringKey && (headers[i] instanceof String)) {
				if (((String) headers[i]).equalsIgnoreCase((String) key))
					return i;
			} else {
				if (headers[i].equals(key))
					return i;
			}
		}
		return -1;
	}

	private V remove(int remove) {
		V removed = values[remove];
		for (int i = remove; i < size; i++) {
			if (i == headers.length - 1) {
				headers[i] = null;
				values[i] = null;
			} else {
				headers[i] = headers[i + 1];
				values[i] = values[i + 1];
			}
		}
		if (remove < size)
			size--;
		return removed;
	}

	private void add(K header, V value) {
		if (size == headers.length) {
			// grow the arrays
			@SuppressWarnings("unchecked")
			K[] nh = (K[]) new Object[headers.length + 10];
			K[] newHeaders = nh;
			@SuppressWarnings("unchecked")
			V[] nv = (V[]) new Object[values.length + 10];
			V[] newValues = nv;
			System.arraycopy(headers, 0, newHeaders, 0, headers.length);
			System.arraycopy(values, 0, newValues, 0, values.length);
			headers = newHeaders;
			values = newValues;
		}
		headers[size] = header;
		values[size] = value;
		size++;
	}

	/**
	 * Support case-insensitivity for keys.
	 *
	 * @param key name.
	 */
	public synchronized V get(Object key) {
		int i = -1;
		if ((i = getIndex(key)) != -1)
			return values[i];
		return null;
	}

	/**
	 * Set a header value or optionally replace it if it already exists.
	 *
	 * @param key Key name.
	 * @param value Value of the key or null to remove key.
	 * @param replace A value of true will allow a previous
	 * value of the key to be replaced.  A value of false 
	 * will cause an IllegalArgumentException to be thrown 
	 * if a previous value of the key exists.
	 * @return the previous value to which the key was mapped,
	 * or null if the key did not have a previous mapping.
	 *
	 * @exception IllegalArgumentException If a case-variant of the key is
	 * already present.
	 * @since 3.2
	 */
	public synchronized V set(K key, V value, boolean replace) {
		if (readOnly)
			throw new UnsupportedOperationException();
		if (key instanceof String) {
			@SuppressWarnings("unchecked")
			K k = (K) ((String) key).intern();
			key = k;
		}
		int i = getIndex(key);
		if (value == null) { /* remove */
			if (i != -1)
				return remove(i);
		} else { /* put */
			if (i != -1) { /* duplicate key */
				if (!replace)
					throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key));
				V oldVal = values[i];
				values[i] = value;
				return oldVal;
			}
			add(key, value);
		}
		return null;
	}

	/**
	 * Set a header value.
	 *
	 * @param key Key name.
	 * @param value Value of the key or null to remove key.
	 * @return the previous value to which the key was mapped,
	 * or null if the key did not have a previous mapping.
	 *
	 * @exception IllegalArgumentException If a case-variant of the key is
	 * already present.
	 */
	public synchronized V set(K key, V value) {
		return set(key, value, false);
	}

	public synchronized void setReadOnly() {
		readOnly = true;
	}

	/**
	 * Returns the number of entries (distinct keys) in this dictionary.
	 *
	 * @return  the number of keys in this dictionary.
	 */
	public synchronized int size() {
		return size;
	}

	/**
	 * Tests if this dictionary maps no keys to value. The general contract
	 * for the <tt>isEmpty</tt> method is that the result is true if and only
	 * if this dictionary contains no entries.
	 *
	 * @return  <code>true</code> if this dictionary maps no keys to values;
	 *          <code>false</code> otherwise.
	 */
	public synchronized boolean isEmpty() {
		return size == 0;
	}

	/**
	 * Always throws UnsupportedOperationException.
	 *
	 * @param key header name.
	 * @param value header value.
	 * @throws UnsupportedOperationException
	 */
	public synchronized V put(K key, V value) {
		if (readOnly)
			throw new UnsupportedOperationException();
		return set(key, value, true);
	}

	/**
	 * Always throws UnsupportedOperationException.
	 *
	 * @param key header name.
	 * @throws UnsupportedOperationException
	 */
	public V remove(Object key) {
		throw new UnsupportedOperationException();
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append('{');

		for (int i = 0; i < size; i++) {
			if (i != 0) {
				sb.append(", "); //$NON-NLS-1$
			}
			K header = headers[i];
			if (header == this) {
				sb.append("(this Dictionary)"); //$NON-NLS-1$
			} else {
				sb.append(header);
			}
			sb.append('=');
			V value = values[i];
			if (value == this) {
				sb.append("(this Dictionary)"); //$NON-NLS-1$
			} else {
				sb.append(value);
			}
		}

		sb.append('}');
		return sb.toString();
	}

	public static Headers<String, String> parseManifest(InputStream in) throws BundleException {
		Headers<String, String> headers = new Headers<>(10);
		try {
			ManifestElement.parseBundleManifest(in, headers);
		} catch (IOException e) {
			throw new BundleException(Msg.MANIFEST_IOEXCEPTION, BundleException.MANIFEST_ERROR, e);
		}
		headers.setReadOnly();
		return headers;
	}

	private static class ArrayEnumeration<E> implements Enumeration<E> {
		private E[] array;
		int cur = 0;

		public ArrayEnumeration(E[] array, int size) {
			@SuppressWarnings("unchecked")
			E[] a = (E[]) new Object[size];
			this.array = a;
			System.arraycopy(array, 0, this.array, 0, this.array.length);
		}

		public boolean hasMoreElements() {
			return cur < array.length;
		}

		public E nextElement() {
			return array[cur++];
		}
	}

	public synchronized void clear() {
		if (readOnly)
			throw new UnsupportedOperationException();
	}

	public synchronized boolean containsKey(Object key) {
		return getIndex(key) >= 0;
	}

	public boolean containsValue(Object value) {
		throw new UnsupportedOperationException();
	}

	public Set<Map.Entry<K, V>> entrySet() {
		throw new UnsupportedOperationException();
	}

	public Set<K> keySet() {
		throw new UnsupportedOperationException();
	}

	public void putAll(Map<? extends K, ? extends V> c) {
		throw new UnsupportedOperationException();
	}

	public Collection<V> values() {
		throw new UnsupportedOperationException();
	}
}
