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

/**
 * Default Property Name Expression {@link Resolver} Implementation.
 * <p>
 * This class assists in resolving property names in the following five formats,
 * with the layout of an identifying String in parentheses:
 * <ul>
 * <li><strong>Simple ({@code name})</strong> - The specified
 *     {@code name} identifies an individual property of a particular
 *     JavaBean.  The name of the actual getter or setter method to be used
 *     is determined using standard JavaBeans introspection, so that (unless
 *     overridden by a {@code BeanInfo} class, a property named "xyz"
 *     will have a getter method named {@code getXyz()} or (for boolean
 *     properties only) {@code isXyz()}, and a setter method named
 *     {@code setXyz()}.</li>
 * <li><strong>Nested ({@code name1.name2.name3})</strong> The first
 *     name element is used to select a property getter, as for simple
 *     references above.  The object returned for this property is then
 *     consulted, using the same approach, for a property getter for a
 *     property named {@code name2}, and so on.  The property value that
 *     is ultimately retrieved or modified is the one identified by the
 *     last name element.</li>
 * <li><strong>Indexed ({@code name[index]})</strong> - The underlying
 *     property value is assumed to be an array, or this JavaBean is assumed
 *     to have indexed property getter and setter methods.  The appropriate
 *     (zero-relative) entry in the array is selected.  {@code List}
 *     objects are now also supported for read/write.  You simply need to define
 *     a getter that returns the {@code List}</li>
 * <li><strong>Mapped ({@code name(key)})</strong> - The JavaBean
 *     is assumed to have an property getter and setter methods with an
 *     additional attribute of type {@code java.lang.String}.</li>
 * <li><strong>Combined ({@code name1.name2[index].name3(key)})</strong> -
 *     Combining mapped, nested, and indexed references is also
 *     supported.</li>
 * </ul>
 *
 * @since 1.8.0
 */
public class DefaultResolver implements Resolver {

    private static final char NESTED        = '.';
    private static final char MAPPED_START  = '(';
    private static final char MAPPED_END    = ')';
    private static final char INDEXED_START = '[';
    private static final char INDEXED_END   = ']';

    /**
     * Default Constructor.
     */
    public DefaultResolver() {
    }

    /**
     * Return the index value from the property expression or -1.
     *
     * @param expression The property expression
     * @return The index value or -1 if the property is not indexed
     * @throws IllegalArgumentException If the indexed property is illegally
     * formed or has an invalid (non-numeric) value.
     */
    @Override
    public int getIndex(final String expression) {
        if (expression == null || expression.length() == 0) {
            return -1;
        }
        for (int i = 0; i < expression.length(); i++) {
            final char c = expression.charAt(i);
            if (c == NESTED || c == MAPPED_START) {
                return -1;
            } else if (c == INDEXED_START) {
                final int end = expression.indexOf(INDEXED_END, i);
                if (end < 0) {
                    throw new IllegalArgumentException("Missing End Delimiter");
                }
                final String value = expression.substring(i + 1, end);
                if (value.length() == 0) {
                    throw new IllegalArgumentException("No Index Value");
                }
                int index = 0;
                try {
                    index = Integer.parseInt(value, 10);
                } catch (final Exception e) {
                    throw new IllegalArgumentException("Invalid index value '"
                            + value + "'");
                }
                return index;
            }
        }
        return -1;
    }

    /**
     * Return the map key from the property expression or {@code null}.
     *
     * @param expression The property expression
     * @return The index value
     * @throws IllegalArgumentException If the mapped property is illegally formed.
     */
    @Override
    public String getKey(final String expression) {
        if (expression == null || expression.length() == 0) {
            return null;
        }
        for (int i = 0; i < expression.length(); i++) {
            final char c = expression.charAt(i);
            if (c == NESTED || c == INDEXED_START) {
                return null;
            } else if (c == MAPPED_START) {
                final int end = expression.indexOf(MAPPED_END, i);
                if (end < 0) {
                    throw new IllegalArgumentException("Missing End Delimiter");
                }
                return expression.substring(i + 1, end);
            }
        }
        return null;
    }

    /**
     * Return the property name from the property expression.
     *
     * @param expression The property expression
     * @return The property name
     */
    @Override
    public String getProperty(final String expression) {
        if (expression == null || expression.length() == 0) {
            return expression;
        }
        for (int i = 0; i < expression.length(); i++) {
            final char c = expression.charAt(i);
            if (c == NESTED) {
                return expression.substring(0, i);
            } else if (c == MAPPED_START || c == INDEXED_START) {
                return expression.substring(0, i);
            }
        }
        return expression;
    }

    /**
     * Indicates whether or not the expression
     * contains nested property expressions or not.
     *
     * @param expression The property expression
     * @return The next property expression
     */
    @Override
    public boolean hasNested(final String expression) {
        if (expression == null || expression.length() == 0) {
            return false;
        }
        return remove(expression) != null;
    }

    /**
     * Indicate whether the expression is for an indexed property or not.
     *
     * @param expression The property expression
     * @return {@code true} if the expression is indexed,
     *  otherwise {@code false}
     */
    @Override
    public boolean isIndexed(final String expression) {
        if (expression == null || expression.length() == 0) {
            return false;
        }
        for (int i = 0; i < expression.length(); i++) {
            final char c = expression.charAt(i);
            if (c == NESTED || c == MAPPED_START) {
                return false;
            } else if (c == INDEXED_START) {
                return true;
            }
        }
        return false;
    }

    /**
     * Indicate whether the expression is for a mapped property or not.
     *
     * @param expression The property expression
     * @return {@code true} if the expression is mapped,
     *  otherwise {@code false}
     */
    @Override
    public boolean isMapped(final String expression) {
        if (expression == null || expression.length() == 0) {
            return false;
        }
        for (int i = 0; i < expression.length(); i++) {
            final char c = expression.charAt(i);
            if (c == NESTED || c == INDEXED_START) {
                return false;
            } else if (c == MAPPED_START) {
                return true;
            }
        }
        return false;
    }

    /**
     * Extract the next property expression from the
     * current expression.
     *
     * @param expression The property expression
     * @return The next property expression
     */
    @Override
    public String next(final String expression) {
        if (expression == null || expression.length() == 0) {
            return null;
        }
        boolean indexed = false;
        boolean mapped  = false;
        for (int i = 0; i < expression.length(); i++) {
            final char c = expression.charAt(i);
            if (indexed) {
                if (c == INDEXED_END) {
                    return expression.substring(0, i + 1);
                }
            } else if (mapped) {
                if (c == MAPPED_END) {
                    return expression.substring(0, i + 1);
                }
            } else {
                if (c == NESTED) {
                    return expression.substring(0, i);
                } else if (c == MAPPED_START) {
                    mapped = true;
                } else if (c == INDEXED_START) {
                    indexed = true;
                }
            }
        }
        return expression;
    }

    /**
     * Remove the last property expression from the
     * current expression.
     *
     * @param expression The property expression
     * @return The new expression value, with first property
     * expression removed - null if there are no more expressions
     */
    @Override
    public String remove(final String expression) {
        if (expression == null || expression.length() == 0) {
            return null;
        }
        final String property = next(expression);
        if (expression.length() == property.length()) {
            return null;
        }
        int start = property.length();
        if (expression.charAt(start) == NESTED) {
            start++;
        }
        return expression.substring(start);
    }
}
