package org.xbib.datastructures.immutable;

import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

public class ImmutableEntry<K extends Object, V extends Object> extends AbstractMapEntry<K, V> {
    final K key;
    final V value;

    public ImmutableEntry(K key, V value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public final K getKey() {
        return key;
    }

    @Override
    public final V getValue() {
        return value;
    }

    @Override
    public final V setValue(V value) {
        throw new UnsupportedOperationException();
    }

    /**
     * Returns an unmodifiable view of the specified map entry. The {@link ImmutableEntry#setValue} operation
     * throws an {@link UnsupportedOperationException}. This also has the side effect of redefining
     * {@code equals} to comply with the Entry contract, to avoid a possible nefarious implementation
     * of equals.
     *
     * @param entry the entry for which to return an unmodifiable view
     * @return an unmodifiable view of the entry
     */
    static <K extends Object, V extends Object> Map.Entry<K, V> unmodifiableEntry(final Map.Entry<? extends K, ? extends V> entry) {
        Objects.requireNonNull(entry);
        return new AbstractMapEntry<K, V>() {
            @Override
            public K getKey() {
                return entry.getKey();
            }

            @Override
            public V getValue() {
                return entry.getValue();
            }
        };
    }

    static <K extends Object, V extends Object> UnmodifiableIterator<Map.Entry<K, V>> unmodifiableEntryIterator(final Iterator<Map.Entry<K, V>> entryIterator) {
        return new UnmodifiableIterator<Map.Entry<K, V>>() {
            @Override
            public boolean hasNext() {
                return entryIterator.hasNext();
            }

            @Override
            public Map.Entry<K, V> next() {
                return unmodifiableEntry(entryIterator.next());
            }
        };
    }
}
