/*
 *  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.myfaces.html5.renderkit.util;

import org.apache.myfaces.html5.component.util.ComponentUtils;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.el.ValueExpression;
import javax.faces.application.ProjectStage;
import javax.faces.component.UIComponent;
import javax.faces.component.UISelectItem;
import javax.faces.component.UISelectItems;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

// ATTENTION
// This class is associated with javax.faces.component._SelectItemsIterator.
// Changes here should also be applied to this class.

/**
 * @author Mathias Broekelmann (latest modification by $Author$)
 * @author Jakob Korherr (jsf 2.0)
 * @version $Revision$ $Date$
 */
public class SelectItemsIterator implements Iterator<SelectItem>
{
    private static final Logger log = Logger.getLogger(SelectItemsIterator.class.getName());

    private static final String VAR_PROP = JsfProperties.VAR_PROP;
    private static final String ITEM_VALUE_PROP = JsfProperties.ITEM_VALUE_PROP;
    private static final String ITEM_LABEL_PROP = JsfProperties.ITEM_LABEL_PROP;
    private static final String ITEM_DESCRIPTION_PROP = JsfProperties.ITEM_DESCRIPTION_PROP;
    private static final String ITEM_DISABLED_PROP = JsfProperties.ITEM_DISABLED_PROP;
    private static final String ITEM_LABEL_ESCAPED_PROP = JsfProperties.ITEM_LABEL_ESCAPED_PROP;
    private static final String NO_SELECTION_VALUE_PROP = JsfProperties.NO_SELECTION_VALUE_PROP;

    private final Iterator<UIComponent> _children;
    private Iterator<? extends Object> _nestedItems;
    private SelectItem _nextItem;
    private UISelectItems _currentUISelectItems;
    private FacesContext _facesContext;

    public SelectItemsIterator(UIComponent selectItemsParent, FacesContext facesContext)
    {
        _children = selectItemsParent.getChildren().iterator();
        _facesContext = facesContext;
    }

    @SuppressWarnings("unchecked")
    public boolean hasNext()
    {
        if (_nextItem != null)
        {
            return true;
        }
        if (_nestedItems != null)
        {
            if (_nestedItems.hasNext())
            {
                return true;
            }
            _nestedItems = null;
        }
        if (_children.hasNext())
        {
            UIComponent child = _children.next();
            // When there is other components nested that does
            // not extends from UISelectItem or UISelectItems
            // the behavior for this iterator is just skip this
            // element(s) until an element that extends from these
            // classes are found. If there is no more elements
            // that conform this condition, just return false.
            while (!(child instanceof UISelectItem) && !(child instanceof UISelectItems))
            {
                // Try to skip it
                if (_children.hasNext())
                {
                    // Skip and do the same check
                    child = _children.next();
                }
                else
                {
                    // End loop, so the final result is return false,
                    // since there are no more components to iterate.
                    return false;
                }
            }
            if (child instanceof UISelectItem)
            {
                UISelectItem uiSelectItem = (UISelectItem) child;
                Object item = uiSelectItem.getValue();
                if (item == null)
                {
                    // no value attribute --> create the SelectItem out of the other attributes
                    Object itemValue = uiSelectItem.getItemValue();
                    String label = uiSelectItem.getItemLabel();
                    String description = uiSelectItem.getItemDescription();
                    boolean disabled = uiSelectItem.isItemDisabled();
                    boolean escape = uiSelectItem.isItemEscaped();
                    boolean noSelectionOption = uiSelectItem.isNoSelectionOption();
                    if (label == null)
                    {
                        label = itemValue.toString();
                    }
                    item = new SelectItem(itemValue, label, description, disabled, escape, noSelectionOption);
                }
                else if (!(item instanceof SelectItem))
                {
                    ValueExpression expression = uiSelectItem.getValueExpression("value");
                    throw new IllegalArgumentException("ValueExpression '"
                            + (expression == null ? null : expression.getExpressionString()) + "' of UISelectItem : "
                            + ComponentUtils.getPathToComponent(child) + " does not reference an Object of type SelectItem");
                }
                _nextItem = (SelectItem) item;
                return true;
            }
            else if (child instanceof UISelectItems)
            {
                _currentUISelectItems = ((UISelectItems) child);
                Object value = _currentUISelectItems.getValue();

                if (value instanceof SelectItem)
                {
                    _nextItem = (SelectItem) value;
                    return true;
                }
                else if (value != null && value.getClass().isArray())
                {
                    // value is any kind of array (primitive or non-primitive)
                    // --> we have to use class Array to get the values
                    final int length = Array.getLength(value);
                    Collection<Object> items = new ArrayList<Object>(length);
                    for (int i = 0; i < length; i++)
                    {
                        items.add(Array.get(value, i));
                    }
                    _nestedItems = items.iterator();
                    return hasNext();
                }
                else if (value instanceof Iterable)
                {
                    // value is Iterable --> Collection, DataModel,...
                    _nestedItems = ((Iterable<?>) value).iterator();
                    return hasNext();
                }
                else if (value instanceof Map)
                {
                    Map<Object, Object> map = ((Map<Object, Object>) value);
                    Collection<SelectItem> items = new ArrayList<SelectItem>(map.size());
                    for (Map.Entry<Object, Object> entry : map.entrySet())
                    {
                        items.add(new SelectItem(entry.getValue(), entry.getKey().toString()));
                    }

                    _nestedItems = items.iterator();
                    return hasNext();
                }
                else
                {
                    Level level = Level.FINE;
                    if (!_facesContext.isProjectStage(ProjectStage.Production))
                    {
                        level = Level.WARNING;
                    }

                    if (log.isLoggable(level))
                    {
                        ValueExpression expression = _currentUISelectItems.getValueExpression("value");
                        log.log(level, "ValueExpression {0} of UISelectItems with component-path {1}"
                                + " does not reference an Object of type SelectItem,"
                                + " array, Iterable or Map, but of type: {2}",
                                new Object[] {
                                    (expression == null ? null : expression.getExpressionString()),
                                    ComponentUtils.getPathToComponent(child),
                                    (value == null ? null : value.getClass().getName())
                                });
                    }
                }
            }
        }
        return false;
    }

    public SelectItem next()
    {
        if (!hasNext())
        {
            throw new NoSuchElementException();
        }
        if (_nextItem != null)
        {
            SelectItem value = _nextItem;
            _nextItem = null;
            return value;
        }
        if (_nestedItems != null)
        {
            Object item = _nestedItems.next();

            if (!(item instanceof SelectItem))
            {
                // check new params of SelectItems (since 2.0): itemValue, itemLabel, itemDescription,...
                // Note that according to the spec UISelectItems does not provide Getter and Setter
                // methods for this values, so we have to use the attribute map
                Map<String, Object> attributeMap = _currentUISelectItems.getAttributes();

                // write the current item into the request map under the key listed in var, if available
                boolean wroteRequestMapVarValue = false;
                Object oldRequestMapVarValue = null;
                final String var = (String) attributeMap.get(VAR_PROP);
                if(var != null && !"".equals(var))
                {
                    // save the current value of the key listed in var from the request map
                    oldRequestMapVarValue = _facesContext.getExternalContext().getRequestMap().put(var, item);
                    wroteRequestMapVarValue = true;
                }

                // check the itemValue attribute
                Object itemValue = attributeMap.get(ITEM_VALUE_PROP);
                if (itemValue == null)
                {
                    // the itemValue attribute was not provided
                    // --> use the current item as the itemValue
                    itemValue = item;
                }

                // Spec: When iterating over the select items, toString()
                // must be called on the string rendered attribute values
                Object itemLabel = attributeMap.get(ITEM_LABEL_PROP);
                if (itemLabel == null)
                {
                    itemLabel = itemValue.toString();
                }
                else
                {
                    itemLabel = itemLabel.toString();
                }
                Object itemDescription = attributeMap.get(ITEM_DESCRIPTION_PROP);
                if (itemDescription != null)
                {
                    itemDescription = itemDescription.toString();
                }
                Boolean itemDisabled = getBooleanAttribute(_currentUISelectItems, ITEM_DISABLED_PROP, false);
                Boolean itemLabelEscaped = getBooleanAttribute(_currentUISelectItems, ITEM_LABEL_ESCAPED_PROP, true);
                Object noSelectionValue = attributeMap.get(NO_SELECTION_VALUE_PROP);
                item = new SelectItem(itemValue,
                        (String) itemLabel,
                        (String) itemDescription,
                        itemDisabled,
                        itemLabelEscaped,
                        itemValue.equals(noSelectionValue));

                // remove the value with the key from var from the request map, if previously written
                if(wroteRequestMapVarValue)
                {
                    // If there was a previous value stored with the key from var in the request map, restore it
                    if (oldRequestMapVarValue != null)
                    {
                        _facesContext.getExternalContext()
                                .getRequestMap().put(var, oldRequestMapVarValue);
                    }
                    else
                    {
                        _facesContext.getExternalContext()
                                .getRequestMap().remove(var);
                    }
                }
            }
            return (SelectItem) item;
        }
        throw new NoSuchElementException();
    }

    public void remove()
    {
        throw new UnsupportedOperationException();
    }

    private boolean getBooleanAttribute(UIComponent component, String attrName, boolean defaultValue)
    {
        Object value = component.getAttributes().get(attrName);
        if (value == null)
        {
            return defaultValue;
        }
        else if (value instanceof Boolean)
        {
            return (Boolean) value;
        }
        else
        {
            // If the value is a String, parse the boolean.
            // This makes the following code work: <tag attribute="true" />,
            // otherwise you would have to write <tag attribute="#{true}" />.
            return Boolean.valueOf(value.toString());
        }
    }

}
