/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     12/14/2017-3.0 Tomas Kraus
//       - 522635: ConcurrentModificationException when triggering lazy load from conforming query
package org.eclipse.persistence.internal.identitymaps;

import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Abstract {@link Enumeration} interface implementation for {@link IdentityMap}
 * interface. Allows to iterate over {@link CacheKey} instances stored in the map.
 *
 * @param <T> type of iterated {@link CacheKey} content
 */
public abstract class AbstractIdentityMapEnumeration<T> implements Enumeration<T> {

    /** {@link CacheKey} instances iterator. */
    protected final Iterator<CacheKey> cacheKeysIterator;

    /** Next key to be returned. */
    protected CacheKey nextKey;

    /** Value of {@code true} if readLocks should be checked or false otherwise. */
    protected boolean shouldCheckReadLocks;

    /**
     * Creates an instance of {@link CacheKey} content enumeration.
     *
     * @param keys {@link Collection} of {@link CacheKey} instances to be iterated
     * @param shouldCheckReadLocks value of {@code true} if read lock on the {@link CacheKey}
     *        instances should be checked or {@code false} otherwise
     */
    protected AbstractIdentityMapEnumeration(Collection<CacheKey> keys, boolean shouldCheckReadLocks) {
        this.shouldCheckReadLocks = shouldCheckReadLocks;
        this.cacheKeysIterator = keys.iterator();
    }

    /**
     * Check whether this enumeration contains more elements.
     *
     * @return value of {@code true} if this enumeration object contains at least
     *         one more element to provide or {@code false} otherwise
     */
    @Override
    public boolean hasMoreElements() {
        this.nextKey = getNextCacheKey();
        return this.nextKey != null;
    }

    /**
     * Get next element of {@link CacheKey} content enumeration if this enumeration
     * object has at least one more element to provide.
     * It it expected that this method will be implemented using {@link #getNextElement()}
     * in child classes.
     *
     * @return the next element of this enumeration
     * @exception NoSuchElementException if no more elements exist
     */
    @Override
    public abstract T nextElement();

    /**
     * Get next {@link CacheKey} instance from iterator.
     *
     * @return next {@link CacheKey} instance or {@code null} if there is no more
     *         instance to provide
     */
    private CacheKey getNextCacheKey() {
        CacheKey key = null;
        while (cacheKeysIterator.hasNext() && (key == null)) {
            key = cacheKeysIterator.next();
        }
        return key;
    }

    /**
     * Get next element of {@link CacheKey} instances enumeration if this enumeration
     * object has at least one more element to provide.
     *
     * @return the next element of this enumeration
     * @exception NoSuchElementException  if no more elements exist
     */
    protected CacheKey getNextElement() {
        if (this.nextKey == null) {
            throw new NoSuchElementException("AbstractIdentityMapEnumeration nextElement");
        }
        // The read lock check is for avoidance of half built objects being returned.
        // bug 275724: Added shouldCheckReadLocks to avoid the read lock check when invalidating.
        if (shouldCheckReadLocks) {
            this.nextKey.checkReadLock();
        }
        return this.nextKey;
    }

}
