/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.beanutils2;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * <p>Implementation of {@code java.util.Iterator} returned by the
 * {@code iterator()} method of {@link ResultSetDynaClass}.  Each
 * object returned by this iterator will be a {@link DynaBean} that
 * represents a single row from the result set being wrapped.</p>
 *
 */

public class ResultSetIterator implements DynaBean, Iterator<DynaBean> {



    /**
     * <p>Construct an {@code Iterator} for the result set being wrapped
     * by the specified {@link ResultSetDynaClass}.</p>
     *
     * @param dynaClass The {@link ResultSetDynaClass} wrapping the
     *  result set we will iterate over
     */
    ResultSetIterator(final ResultSetDynaClass dynaClass) {

        this.dynaClass = dynaClass;

    }



    /**
     * <p>Flag indicating whether the result set is currently positioned at a
     * row for which we have not yet returned an element in the iteration.</p>
     */
    protected boolean current = false;

    /**
     * <p>The {@link ResultSetDynaClass} we are associated with.</p>
     */
    protected ResultSetDynaClass dynaClass = null;

    /**
     * <p>Flag indicating whether the result set has indicated that there are
     * no further rows.</p>
     */
    protected boolean eof = false;



    /**
     * Does the specified mapped property contain a value for the specified
     * key value?
     *
     * @param name Name of the property to check
     * @param key Name of the key to check
     * @return {@code true} if the mapped property contains a value for
     * the specified key, otherwise {@code false}
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     */
    @Override
    public boolean contains(final String name, final String key) {

        throw new UnsupportedOperationException
            ("FIXME - mapped properties not currently supported");

    }

    /**
     * Return the value of a simple property with the specified name.
     *
     * @param name Name of the property whose value is to be retrieved
     * @return The property's value
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     */
    @Override
    public Object get(final String name) {

        if (dynaClass.getDynaProperty(name) == null) {
            throw new IllegalArgumentException(name);
        }
        try {
            return dynaClass.getObjectFromResultSet(name);
        } catch (final SQLException e) {
            throw new RuntimeException
                ("get(" + name + "): SQLException: " + e);
        }

    }

    /**
     * Return the value of an indexed property with the specified name.
     *
     * @param name Name of the property whose value is to be retrieved
     * @param index Index of the value to be retrieved
     * @return The indexed property's value
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws IllegalArgumentException if the specified property
     *  exists, but is not indexed
     * @throws IndexOutOfBoundsException if the specified index
     *  is outside the range of the underlying property
     * @throws NullPointerException if no array or List has been
     *  initialized for this property
     */
    @Override
    public Object get(final String name, final int index) {

        throw new UnsupportedOperationException
            ("FIXME - indexed properties not currently supported");

    }

    /**
     * Return the value of a mapped property with the specified name,
     * or {@code null} if there is no value for the specified key.
     *
     * @param name Name of the property whose value is to be retrieved
     * @param key Key of the value to be retrieved
     * @return The mapped property's value
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws IllegalArgumentException if the specified property
     *  exists, but is not mapped
     */
    @Override
    public Object get(final String name, final String key) {

        throw new UnsupportedOperationException
            ("FIXME - mapped properties not currently supported");

    }

    /**
     * Return the {@code DynaClass} instance that describes the set of
     * properties available for this DynaBean.
     *
     * @return The associated DynaClass
     */
    @Override
    public DynaClass getDynaClass() {

        return this.dynaClass;

    }

    /**
     * Remove any existing value for the specified key on the
     * specified mapped property.
     *
     * @param name Name of the property for which a value is to
     *  be removed
     * @param key Key of the value to be removed
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     */
    @Override
    public void remove(final String name, final String key) {

        throw new UnsupportedOperationException
            ("FIXME - mapped operations not currently supported");

    }

    /**
     * Set the value of a simple property with the specified name.
     *
     * @param name Name of the property whose value is to be set
     * @param value Value to which this property is to be set
     *
     * @throws ConversionException if the specified value cannot be
     *  converted to the type required for this property
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws NullPointerException if an attempt is made to set a
     *  primitive property to null
     */
    @Override
    public void set(final String name, final Object value) {

        if (dynaClass.getDynaProperty(name) == null) {
            throw new IllegalArgumentException(name);
        }
        try {
            dynaClass.getResultSet().updateObject(name, value);
        } catch (final SQLException e) {
            throw new RuntimeException
                ("set(" + name + "): SQLException: " + e);
        }

    }

    /**
     * Set the value of an indexed property with the specified name.
     *
     * @param name Name of the property whose value is to be set
     * @param index Index of the property to be set
     * @param value Value to which this property is to be set
     *
     * @throws ConversionException if the specified value cannot be
     *  converted to the type required for this property
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws IllegalArgumentException if the specified property
     *  exists, but is not indexed
     * @throws IndexOutOfBoundsException if the specified index
     *  is outside the range of the underlying property
     */
    @Override
    public void set(final String name, final int index, final Object value) {

        throw new UnsupportedOperationException
            ("FIXME - indexed properties not currently supported");

    }

    /**
     * Set the value of a mapped property with the specified name.
     *
     * @param name Name of the property whose value is to be set
     * @param key Key of the property to be set
     * @param value Value to which this property is to be set
     *
     * @throws ConversionException if the specified value cannot be
     *  converted to the type required for this property
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws IllegalArgumentException if the specified property
     *  exists, but is not mapped
     */
    @Override
    public void set(final String name, final String key, final Object value) {

        throw new UnsupportedOperationException
            ("FIXME - mapped properties not currently supported");

    }



    /**
     * <p>Return {@code true} if the iteration has more elements.</p>
     *
     * @return {@code true} if the result set has another
     * row, otherwise {@code false}
     */
    @Override
    public boolean hasNext() {

        try {
            advance();
            return !eof;
        } catch (final SQLException e) {
            throw new RuntimeException("hasNext():  SQLException:  " + e);
        }

    }

    /**
     * <p>Return the next element in the iteration.</p>
     *
     * @return advance to the new row and return this
     */
    @Override
    public DynaBean next() {

        try {
            advance();
            if (eof) {
                throw new NoSuchElementException();
            }
            current = false;
            return this;
        } catch (final SQLException e) {
            throw new RuntimeException("next():  SQLException:  " + e);
        }

    }

    /**
     * <p>Remove the current element from the iteration.  This method is
     * not supported.</p>
     */
    @Override
    public void remove() {

        throw new UnsupportedOperationException("remove()");

    }



    /**
     * <p>Advance the result set to the next row, if there is not a current
     * row (and if we are not already at eof).</p>
     *
     * @throws SQLException if the result set throws an exception
     */
    protected void advance() throws SQLException {

        if (!current && !eof) {
            if (dynaClass.getResultSet().next()) {
                current = true;
                eof = false;
            } else {
                current = false;
                eof = true;
            }
        }

    }

}
