package org.xbib.datastructures.immutable;

import java.util.Collections;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Spliterator;

/**
 * Implementation of {@link ImmutableList} with exactly one element.
 */
final class SingletonImmutableList<E> extends ImmutableList<E> {

    final transient E element;

    SingletonImmutableList(E element) {
        this.element = Objects.requireNonNull(element);
    }

    @Override
    public E get(int index) {
        checkElementIndex(index, 1, "index");
        return element;
    }

    @Override
    public UnmodifiableIterator<E> iterator() {
        return singletonIterator(element);
    }

    @Override
    public Spliterator<E> spliterator() {
        return Collections.singleton(element).spliterator();
    }

    @Override
    public int size() {
        return 1;
    }

    @Override
    public ImmutableList<E> subList(int fromIndex, int toIndex) {
        checkPositionIndexes(fromIndex, toIndex, 1);
        return (fromIndex == toIndex) ? ImmutableList.of() : this;
    }

    @Override
    public String toString() {
        return '[' + element.toString() + ']';
    }

    @Override
    boolean isPartialView() {
        return false;
    }

    /**
     * Returns an iterator containing only {@code value}.
     *
     * <p>The {@link Iterable} equivalent of this method is {@link Collections#singleton}.
     */
    public static <T extends Object> UnmodifiableIterator<T> singletonIterator(T value) {
        return new UnmodifiableIterator<T>() {
            boolean done;

            @Override
            public boolean hasNext() {
                return !done;
            }

            @Override
            public T next() {
                if (done) {
                    throw new NoSuchElementException();
                }
                done = true;
                return value;
            }
        };
    }
}
