/*
 * 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.jelly.expression;

import java.util.Collections;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.iterators.ArrayIterator;
import org.apache.commons.collections.iterators.EnumerationIterator;
import org.apache.commons.collections.iterators.SingletonIterator;

import org.apache.commons.jelly.JellyContext;
import org.apache.commons.jelly.JellyTagException;
import org.apache.commons.lang.StringUtils;

/** <p><code>ExpressionSupport</code>
  * an abstract base class for Expression implementations
  * which provides default implementations of some of the
  * typesafe evaluation methods.</p>
  *
  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  * @version $Revision$
  */
public abstract class ExpressionSupport implements Expression {

    protected static final Iterator EMPTY_ITERATOR = Collections.EMPTY_LIST.iterator();

    // inherit javadoc from interface
    public String evaluateAsString(JellyContext context) {
        Object value = evaluateRecurse(context);
        // sometimes when Jelly is used inside Maven the value
        // of an expression can actually be an expression.
        // e.g. ${foo.bar} can lookup "foo.bar" in a Maven context
        // which could actually be an expression

        if ( value != null ) {
            return value.toString();
        }
        return null;
    }


    // inherit javadoc from interface
    public Object evaluateRecurse(JellyContext context) {
        Object value = evaluate(context);
        if (value instanceof Expression) {
            Expression expression = (Expression) value;
            return expression.evaluateRecurse(context);
        }
        return value;
    }

    // inherit javadoc from interface
    public boolean evaluateAsBoolean(JellyContext context) {
        Object value = evaluateRecurse(context);
        if ( value instanceof Boolean ) {
            Boolean b = (Boolean) value;
            return b.booleanValue();
        }
        else if ( value instanceof String ) {
            // return Boolean.getBoolean( (String) value );
            String str = (String) value;

            return ( str.equalsIgnoreCase( "on" )
                 ||
                 str.equalsIgnoreCase( "yes" )
                 ||
                 str.equals( "1" )
                 ||
                 str.equalsIgnoreCase( "true" ) );

        }
        return false;
    }

    // inherit javadoc from interface
    public Iterator evaluateAsIterator(JellyContext context) {
        Object value = evaluateRecurse(context);
        if ( value == null ) {
            return EMPTY_ITERATOR;
        } else if ( value instanceof Iterator ) {
            return (Iterator) value;
        } else if ( value instanceof List ) {
            List list = (List) value;
            return list.iterator();
        } else if ( value instanceof Map ) {
            Map map = (Map) value;
            return map.entrySet().iterator();
        } else if ( value.getClass().isArray() ) {
            return new ArrayIterator( value );
        } else if ( value instanceof Enumeration ) {
            return new EnumerationIterator((Enumeration ) value);
        } else if ( value instanceof Collection ) {
          Collection collection = (Collection) value;
          return collection.iterator();
        } else if ( value instanceof String ) {
           String[] array = StringUtils.split((String) value, "," );
           array = StringUtils.stripAll( array );
           return new ArrayIterator( array );
        } else {
            // XXX: should we return single iterator?
            return new SingletonIterator( value );
        }
    }
}
