/*******************************************************************************
 *  Copyright (c) 2007, 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.equinox.internal.p2.core.helpers;

import java.util.*;

/**
 * A Properties collection that maintains the order of insertion.
 * <p>
 * This class is used to store properties similar to {@link java.util.Properties}.
 * In particular both keys and values are strings and must be not null.
 * However this class is somewhat simplified and does not implement Cloneable,
 * Serializable and Hashtable.
 * <p>
 * In contrast to java.util.Properties this class maintains the order by which
 * properties are added. This is implemented using a {@link LinkedHashMap}.
 * <p>
 * The class does not support default properties as they can be expressed by
 * creating java.util.Properties hierarchies.
 */
public class OrderedProperties extends Dictionary<String, String> implements Map<String, String> {

	LinkedHashMap<String, String> propertyMap = null;

	public static OrderedProperties unmodifiableProperties(Map<String, String> properties) {
		return new UnmodifiableProperties(properties);
	}

	public OrderedProperties() {
		super();
	}

	public OrderedProperties(int size) {
		super();
		propertyMap = new LinkedHashMap<>(size);
	}

	public OrderedProperties(Map<String, String> properties) {
		super();
		propertyMap = new LinkedHashMap<>(properties.size());
		putAll(properties);
	}

	/**
	 * Set the property value.
	 * <p>
	 * If a property with the key already exists, the previous
	 * value is replaced. Otherwise a new property is added at
	 * the end collection.
	 *
	 * @param key   must not be null
	 * @param value must not be null
	 * @return previous value associated with specified key, or <tt>null</tt>
	 *	       if there was no mapping for key.
	 */
	public Object setProperty(String key, String value) {
		init();
		return propertyMap.put(key.intern(), value);
	}

	public String getProperty(String key) {
		return (propertyMap == null ? null : propertyMap.get(key));
	}

	/**
	 *	Initialize the map.
	 */
	private void init() {
		if (propertyMap == null) {
			propertyMap = new LinkedHashMap<>();
		}
	}

	@Override
	public int size() {
		return propertyMap == null ? 0 : propertyMap.size();
	}

	@Override
	public boolean isEmpty() {
		return propertyMap == null ? true : propertyMap.isEmpty();
	}

	@Override
	public synchronized void clear() {
		propertyMap = null;
	}

	@Override
	public String put(String key, String value) {
		init();
		return propertyMap.put(key.intern(), value);
	}

	@Override
	public boolean containsKey(Object key) {
		return propertyMap != null ? propertyMap.containsKey(key) : false;
	}

	@Override
	public boolean containsValue(Object value) {
		return propertyMap != null ? propertyMap.containsValue(value) : false;
	}

	@Override
	public Set<Map.Entry<String, String>> entrySet() {
		return propertyMap != null ? propertyMap.entrySet() : Collections.emptySet();
	}

	@Override
	public String get(Object key) {
		return propertyMap != null ? propertyMap.get(key) : null;
	}

	@Override
	public Set<String> keySet() {
		return propertyMap != null ? propertyMap.keySet() : Collections.emptySet();
	}

	@Override
	public void putAll(Map<? extends String, ? extends String> arg0) {
		init();
		propertyMap.putAll(arg0);
	}

	@Override
	public String remove(Object key) {
		return propertyMap != null ? propertyMap.remove(key) : null;
	}

	@Override
	public Collection<String> values() {
		return propertyMap != null ? propertyMap.values() : Collections.emptyList();
	}

	@Override
	public boolean equals(Object o) {
		if (o == this)
			return true;
		if (o instanceof OrderedProperties) {
			OrderedProperties rhs = (OrderedProperties) o;
			if (rhs.propertyMap == this.propertyMap)
				return true;
			if (rhs.propertyMap == null)
				return this.propertyMap.isEmpty();
			else if (this.propertyMap == null)
				return rhs.isEmpty();
			return rhs.propertyMap.equals(this.propertyMap);
		}
		if (this.propertyMap == null) {
			if (o instanceof Map<?, ?>)
				return ((Map<?, ?>) o).isEmpty();
			return false;
		}
		return this.propertyMap.equals(o);
	}

	@Override
	public int hashCode() {
		return propertyMap == null || propertyMap.isEmpty() ? 0 : propertyMap.hashCode();
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(propertyMap);
		return sb.toString();
	}

	private class StringsEnum implements Enumeration<String> {

		private final Iterator<String> iterator;

		public StringsEnum(Collection<String> elems) {
			this.iterator = elems.iterator();
		}

		@Override
		public boolean hasMoreElements() {
			return iterator.hasNext();
		}

		@Override
		public String nextElement() {
			return iterator.next();
		}
	}

	@Override
	public Enumeration<String> elements() {
		return new StringsEnum(propertyMap.values());
	}

	@Override
	public Enumeration<String> keys() {
		return new StringsEnum(propertyMap.keySet());
	}

	private static class UnmodifiableProperties extends OrderedProperties {

		UnmodifiableProperties(Map<String, String> properties) {
			super();
			for (Map.Entry<String, String> entry : properties.entrySet()) {
				super.put(entry.getKey(), entry.getValue());
			}
		}

		@Override
		public synchronized Object setProperty(String key, String value) {
			throw new UnsupportedOperationException();
		}

		@Override
		public synchronized String put(String key, String value) {
			throw new UnsupportedOperationException();
		}

		@Override
		public synchronized String remove(Object key) {
			throw new UnsupportedOperationException();
		}

		@Override
		public synchronized void putAll(Map<? extends String, ? extends String> t) {
			throw new UnsupportedOperationException();
		}

		@Override
		public synchronized void clear() {
			throw new UnsupportedOperationException();
		}

	}

}
