/*
 * 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.test.el;

import java.util.ArrayList;
import java.util.List;

import javax.el.ELContext;
import javax.el.ValueExpression;

/**
 * A value expression implementation that is capable of handling composite expressions.
 * It handles composites expressions but creating a list of 'simple' expressions which 
 * are 'pure', only literal text or only references like #{}
 * 
 * @author Rudy De Busscher
 * @since 1.0.0
 */
public class MockCompositeValueExpression extends MockValueExpression
{

    private static final long serialVersionUID = 2645070462654392076L;

    private List<ValueExpression> valueExpressionChain;

    public MockCompositeValueExpression(String expression, Class expectedType)
    {

        super("#{}", expectedType);
        buildExpressionChain(expression, expectedType);

    }

    private void buildExpressionChain(String expression, Class expectedType)
    {
        valueExpressionChain = new ArrayList<ValueExpression>();
        StringBuilder parser = new StringBuilder(expression);
        int pos = getStartPositionOfReference(parser);
        while (pos > -1 || parser.length() > 0)
        {
            // We have a constant first
            if (pos > 0)
            {
                valueExpressionChain.add(new MockValueExpression(parser
                        .substring(0, pos), expectedType));
                parser.delete(0, pos);
            }
            // We have an el, maybe literal at the end
            if (pos == 0)
            {
                int posBracket = parser.indexOf("}");
                valueExpressionChain.add(new MockValueExpression(parser
                        .substring(0, posBracket + 1), expectedType));

                parser.delete(0, posBracket + 1);
            }
            // Only literal
            if (pos == -1)
            {
                valueExpressionChain.add(new MockValueExpression(parser
                        .toString(), expectedType));

                parser.setLength(0);
            }
            pos = getStartPositionOfReference(parser);
        }
    }

    @Override
    public Class getType(ELContext context)
    {
        switch (valueExpressionChain.size())
        {
        case 0:
            return null;
        case 1:
            return valueExpressionChain.get(0).getType(context);
        default:
            return String.class;
        }
    }

    @Override
    public Object getValue(ELContext context)
    {
        if (valueExpressionChain.size() > 1)
        {
            // Well only composite strings are supported.

            StringBuilder result = new StringBuilder();
            for (ValueExpression valueExpression : valueExpressionChain)
            {
                result.append(valueExpression.getValue(context));
            }
            return result.toString();
        }
        else
        {
            if (valueExpressionChain.size() == 1)
            {
                return valueExpressionChain.get(0).getValue(context);
            }
            else
            {
                return null;
            }
        }
    }

    @Override
    public void setValue(ELContext context, Object value)
    {
        if (!isReadOnly(context))
        {
            valueExpressionChain.get(0).setValue(context, value);
        }
        else
        {
            throw new IllegalArgumentException(
                    "We can only set value on NON composite expressions like #{foo}");
        }
    }

    @Override
    public String getExpressionString()
    {
        StringBuilder result = new StringBuilder();
        for (ValueExpression valueExpression : valueExpressionChain)
        {
            result.append(valueExpression.getExpressionString());
        }
        return result.toString();
    }

    @Override
    public boolean isReadOnly(ELContext context)
    {
        return valueExpressionChain.size() > 1;
    }

    public static int getStartPositionOfReference(StringBuilder expressionPart)
    {
        int result;
        int pos1 = expressionPart.indexOf("#{");
        int pos2 = expressionPart.indexOf("${");

        if (pos1 == -1)
        {
            result = pos1;
        }
        else if (pos2 == -1)
        {
            result = pos1;
        }
        else
        {
            result = Math.min(pos1, pos2);
        }
        return result;

    }

}
