/*
 * 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.extensions.validator.core.el;

import org.apache.myfaces.extensions.validator.internal.UsageCategory;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import org.apache.myfaces.extensions.validator.internal.ToDo;
import org.apache.myfaces.extensions.validator.internal.Priority;
import org.apache.myfaces.extensions.validator.util.ExtValUtils;

/**
 * An instance of this class stores the different parts of an expression string and
 * allows an easier usage of value-bindings.
 *
 * @since 1.x.1
 */
@ToDo(value = Priority.MEDIUM, description = "difference between [ and [' - test with more constellations")
@UsageInformation({UsageCategory.API})
public class ValueBindingExpression
{
    private ValueBindingExpression base;
    private String value;
    private String prefix;
    private String token;

    private static final ELHelper EL_HELPER = ExtValUtils.getELHelper();

    /**
     * The given property is used as new property of the expression.
     * Examples for 'newProperty':<br/>
     * #{bean} -> #{bean.newProperty}
     * <p/>
     * #{bean.property} -> #{bean.newProperty}
     *
     * @param valueBindingExpression The target instance of {@link ValueBindingExpression}
     * @param newProperty The property to use.
     * @return The resulting {@link ValueBindingExpression} (with the new property)
     */
    public static ValueBindingExpression replaceOrAddProperty(ValueBindingExpression valueBindingExpression,
                                                              String newProperty)
    {
        if(valueBindingExpression.getBaseExpression() != null)
        {
            return replaceProperty(valueBindingExpression, newProperty);
        }
        else
        {
            return addProperty(valueBindingExpression, newProperty);
        }
    }

    /**
     * Replace the property in the expression string with the given property.
     *
     * @param valueBindingExpression The valueBindingExpression where we want to replace the property
     * @param newProperty The new property which should replace the existing one.
     * @return The resulting {@link ValueBindingExpression} (with the new property)
     */
    public static ValueBindingExpression replaceProperty(ValueBindingExpression valueBindingExpression,
                                                         String newProperty)
    {
        //TODO adjustments for isDynamicBaseAndProperty
        if(valueBindingExpression.getProperty().endsWith("']"))
        {
            valueBindingExpression = valueBindingExpression.getBaseExpression();
        }

        if(valueBindingExpression.getBaseExpression() != null)
        {
            return addProperty(valueBindingExpression.getBaseExpression(), newProperty);
        }
        else
        {
            return addProperty(valueBindingExpression, newProperty);
        }
    }

    /**
     * Adds the property to the given {@link ValueBindingExpression}.
     *
     * @param valueBindingExpression The valueBindingExpression where we want to add the property
     * @param newProperty The property to add.
     * @return The resulting {@link ValueBindingExpression} (with the new property)
     */
    public static ValueBindingExpression addProperty(ValueBindingExpression valueBindingExpression, String newProperty)
    {
        String sourceExpression = valueBindingExpression.getExpressionString();
        String result = sourceExpression.substring(0, sourceExpression.length() - 1);

        //TODO adjustments for isDynamicBaseAndProperty
        if(newProperty.startsWith("['"))
        {
            return new ValueBindingExpression(result + newProperty + "}");
        }
        else
        {
            return new ValueBindingExpression(result + "." + newProperty + "}");
        }
    }

    /**
     * Creates an instance of a ValueBindingExpression based on a well formed EL expression.
     *
     * @param expression The EL expression
     */
    public ValueBindingExpression(String expression)
    {
        if(!EL_HELPER.isELTermWellFormed(expression))
        {
            throw new IllegalStateException(expression + " is no valid el-expression");
        }

        boolean isDynamicBaseAndProperty = expression.lastIndexOf("']") == -1;
        int index1 = isDynamicBaseAndProperty ? expression.lastIndexOf("]") : expression.lastIndexOf("']");
        int index2 = expression.lastIndexOf(".");

        if(index1 > index2)
        {
            expression = expression.substring(0, index1);

            int index3 = findIndexOfStartingBracket(expression);
            if(isDynamicBaseAndProperty)
            {
                this.value = expression.substring(index3 + 1, index1);

            }
            else
            {
                this.value = expression.substring(index3 + 2, index1);
            }

            this.base = new ValueBindingExpression(expression.substring(0, index3) + "}");
            this.token = isDynamicBaseAndProperty ? "[" : "['";
        }
        else if( index2 > index1)
        {
            this.value = expression.substring(index2 + 1, expression.length() - 1 );
            this.base = new ValueBindingExpression(expression.substring(0, index2) + "}");
            this.token = ".";
        }
        else
        {
            this.value = expression.substring(2, expression.length() - 1);
            this.prefix = expression.substring(0, 1);
        }
    }

    /**
     * The (last) property of the expression.
     * @return The (last) property of the expression.
     */
    public String getProperty()
    {
        this.value = this.value.trim();
        
        if("[".equals(this.token))
        {
            if(this.value.startsWith("'"))
            {
                return this.value.substring(1, this.value.length() - 1);
            }
            //return this.base.value + this.token + this.value.substring(0, this.value.length()) + "']";
        }
        return value;
    }

    public ValueBindingExpression getBaseExpression()
    {
        return base;
    }

    /**
     * Recreates the expression string from which this valueBindingExpression was build. There is no guarantee that the
     * same format is kep, for example {#bean['property']} could become {#bean.property}
     *
     * @return  The expression string equivalent of the valueBindingExpression.
     */
    public String getExpressionString()
    {
        if(this.base != null)
        {
            String baseExpression = this.base.getExpressionString();

            if("['".equals(this.token))
            {
                return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "']}";
            }
            else if("[".equals(this.token))
            {
                return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "]}";
            }
            return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "}";
        }
        else
        {
            return this.prefix + "{" + this.value + "}";
        }
    }

    public String getPrefix()
    {
        if(this.base != null)
        {
            return this.base.getPrefix();
        }
        else
        {
            return prefix;
        }
    }

    public void setPrefix(String prefix)
    {
        if(this.base != null)
        {
            this.base.setPrefix(prefix);
        }
        else
        {
            this.prefix = prefix;
        }
    }

    @Override
    public String toString()
    {
        return getExpressionString();
    }

    @Override
    public int hashCode()
    {
        return getExpressionString().hashCode();
    }

    @Override
    public boolean equals(Object target)
    {
        return target instanceof ValueBindingExpression && getExpressionString()
            .equals(((ValueBindingExpression) target).getExpressionString());
    }

    private int findIndexOfStartingBracket(String expression)
    {
        int closeCount = 0;
        for(int i = expression.length() - 1; i > 0; i--)
        {
            if(expression.charAt(i) == '[')
            {
                closeCount--;
                if(closeCount < 0)
                {
                    return i;
                }
            }
            else if(expression.charAt(i) == ']')
            {
                closeCount++;
            }
        }
        return 0;
    }
}
