//  Copyright 2004, 2008 The Apache Software Foundation
//
// Licensed 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.tapestry.binding;

import ognl.Node;
import ognl.Ognl;
import ognl.OgnlException;
import ognl.TypeConverter;
import ognl.enhance.ExpressionAccessor;
import org.apache.tapestry.*;
import org.apache.tapestry.engine.ExpressionEvaluator;
import org.apache.tapestry.spec.BeanLifecycle;
import org.apache.tapestry.spec.IApplicationSpecification;
import org.apache.tapestry.spec.IBeanSpecification;
import org.apache.tapestry.util.StringSplitter;

import java.util.Map;

/**
 * Implements a dynamic binding, based on getting and fetching values using JavaBeans property access.  This is built
 * upon the <a href="http://www.ognl.org">OGNL</a> library.
 * <p/>
 * <p><b>Optimization of the Expression</b>
 * <p/>
 * <p>There's a lot of room for optimization here because we can count on some portions of the expression to be
 * effectively static.  Note that we type the root object as {@link IComponent}.  We have some expectations that certain
 * properties of the root (and properties reachable from the root) will be constant for the lifetime of the binding. For
 * example, components never change thier page or container.  This means that certain property prefixes can be
 * optimized:
 * <p/>
 * <ul> <li>page <li>container <li>components.<i>name</i> </ul>
 * <p/>
 * <p>This means that once an ExpressionBinding has been triggered, the {@link #toString()} method may return different
 * values for the root component and the expression than was originally set.
 * <p/>
 * <p><b>Identifying Invariants</b>
 * <p/>
 * <p>Most expressions are fully dynamic; they must be resolved each time they are accessed.  This can be somewhat
 * inefficient. Tapestry can identify certain paths as invariant:
 * <p/>
 * <ul> <li>A component within the page hierarchy <li>An {@link org.apache.tapestry.IAsset} from then assets map
 * (property <code>assets</code>) <li>A {@link org.apache.tapestry.IActionListener} from the listener map (property
 * <code>listeners</code>) <li>A bean with a {@link org.apache.tapestry.spec.BeanLifecycle#PAGE} lifecycle (property
 * <code>beans</code>) <li>A binding (property <code>bindings</code>) </ul>
 * <p/>
 * <p/>
 * These optimizations have some inherent dangers; they assume that the components have not overidden the specified
 * properties; the last one (concerning helper beans) assumes that the component does inherit from {@link
 * org.apache.tapestry.AbstractComponent}. If this becomes a problem in the future, it may be necessary to have the
 * component itself involved in these determinations.
 *
 * @author Howard Lewis Ship
 * @version $Id$
 * @since 2.2
 */

public class ExpressionBinding extends AbstractBinding
{
    /**
     * The root object against which the nested property name is evaluated.
     */

    private IComponent _root;

    /**
     * The OGNL expression, as a string.
     */

    private String _expression;

    /**
     * If true, then the binding is invariant, and cachedValue is the ultimate value.
     */

    private boolean _invariant = false;

    /**
     * Stores the cached value for the binding, if invariant is true.
     */

    private Object _cachedValue;

    /**
     * Parsed OGNL expression.
     */

    private Node _parsedExpression;

    /**
     * Flag set once the binding has initialized. _cachedValue, _invariant and _final value for _expression are not
     * valid until after initialization.
     */

    private boolean _initialized;

    private IResourceResolver _resolver;

    /**
     * The OGNL context for this binding.  It is retained for the lifespan of the binding once created.
     */

    private Map _context;

    /**
     * Central OGNL expression manager.
     */
    private ExpressionEvaluator _evaluator;

    /**
     * Compiled OGNL expression.
     */

    private ExpressionAccessor _accessor;

    /**
     * Used to detect previous failed attempts at writing values when compiling expressions so that as many expressions
     * as possible can be fully compiled into their java byte form when all objects in the expression are available.
     */
    private boolean _writeFailed;

    /**
     * This is current set to false, to prevent any attempts at bytecode compilation of OGNL expressions.
     */
    private static final boolean EXPRESSION_EVALUATION_ENABLED = false;

    /**
     * Creates a {@link ExpressionBinding} from the root object and an OGNL expression.
     */

    public ExpressionBinding(
            IResourceResolver resolver,
            IComponent root,
            String expression,
            ILocation location)
    {
        super(location);

        _resolver = resolver;
        _root = root;
        _expression = expression;
        _evaluator = root.getPage().getEngine().getExpressionEvaluator();
    }

    public String getExpression()
    {
        return _expression;
    }

    public IComponent getRoot()
    {
        return _root;
    }

    /**
     * Gets the value of the property path, with the assistance of a OGNL.
     *
     * @throws BindingException if an exception is thrown accessing the property.
     */

    public Object getObject()
    {
        initialize();

        if (_invariant)
            return _cachedValue;

        return resolveProperty();
    }

    private Object resolveProperty()
    {
        try
        {
            if (EXPRESSION_EVALUATION_ENABLED && _evaluator.isCompileEnabled() && _accessor == null && !_writeFailed)
            {
                _evaluator.compileExpression(_root, _parsedExpression, _expression);
                _accessor = _parsedExpression.getAccessor();
            }

            if (_accessor != null)
                return _evaluator.read(_root, _accessor);

            return _evaluator.readCompiled(_root, _parsedExpression);
        }
        catch (Throwable t)
        {
            throw new BindingException(
                    Tapestry.format(
                            "ExpressionBinding.unable-to-resolve-expression",
                            _expression,
                            _root),
                    this,
                    t);
        }
    }

    /**
     * Creates an OGNL context used to get or set a value. We may extend this in the future to set additional context
     * variables (such as page, request cycle and engine). An optional type converter will be added to the OGNL context
     * if it is specified as an application extension with the name {@link Tapestry#OGNL_TYPE_CONVERTER}.
     */

    private Map getOgnlContext()
    {
        if (_context == null)
            _context = Ognl.createDefaultContext(_root, _resolver);

        if (_root.getPage() != null)
        {
            if (_root.getPage().getEngine() != null)
            {
                IApplicationSpecification appSpec = _root.getPage().getEngine().getSpecification();

                if (appSpec != null && appSpec.checkExtension(Tapestry.OGNL_TYPE_CONVERTER))
                {
                    TypeConverter typeConverter = (TypeConverter) appSpec.getExtension(
                            Tapestry.OGNL_TYPE_CONVERTER,
                            TypeConverter.class);

                    Ognl.setTypeConverter(_context, typeConverter);
                }
            }
        }

        return _context;
    }

    /**
     * Returns true if the binding is expected to always return the same value.
     */

    public boolean isInvariant()
    {
        initialize();

        return _invariant;
    }

    public void setBoolean(boolean value)
    {
        setObject(value ? Boolean.TRUE : Boolean.FALSE);
    }

    public void setInt(int value)
    {
        setObject(new Integer(value));
    }

    public void setDouble(double value)
    {
        setObject(new Double(value));
    }

    public void setString(String value)
    {
        setObject(value);
    }

    /**
     * Sets up the helper object, but also optimizes the property path and determines if the binding is invarant.
     */

    private void initialize()
    {
        if (_initialized)
            return;

        _initialized = true;

        try
        {
            _parsedExpression = _evaluator.parse(_root, _expression);
        }
        catch (Exception ex)
        {
            throw new BindingException(ex.getMessage(), this, ex);
        }

        if (checkForConstant())
            return;

        try
        {
            if (!Ognl.isSimpleNavigationChain(_parsedExpression, getOgnlContext()))
                return;
        }
        catch (OgnlException ex)
        {
            throw new BindingException(ex.getMessage(), this, ex);
        }

        // Split the expression into individual property names.
        // We then optimize what we can from the expression.  This will
        // shorten the expression and, in some cases, eliminate
        // it.  We also check to see if the binding can be an invariant.

        String[] split = new StringSplitter('.').splitToArray(_expression);

        int count = optimizeRootObject(split);

        // We'ver removed some or all of the initial elements of split
        // but have to account for anything left over.

        if (count == split.length)
        {
            // The property path was something like "page" or "component.foo"
            // and was completely eliminated.

            _expression = null;
            _parsedExpression = null;

            _invariant = true;
            _cachedValue = _root;

            return;
        }

        _expression = reassemble(count, split);
        _parsedExpression = _evaluator.parse(_root, _expression);

        checkForInvariant(count, split);
    }

    /**
     * Looks for common prefixes on the expression (provided pre-split) that are recognized as references to other
     * components.
     *
     * @return the number of leading elements of the split expression that have been removed.
     */

    private int optimizeRootObject(String[] split)
    {
        int i;

        for (i = 0; i < split.length; i++)
        {

            if (split[i].equals("page"))
            {
                _root = _root.getPage();
                continue;
            }

            if (split[i].equals("container"))
            {
                _root = _root.getContainer();
                continue;
            }

            // Here's the tricky one ... if its of the form
            // "components.foo" we can get the named component
            // directly.

            if (split[i].equals("components") && i + 1 < split.length)
            {
                _root = _root.getComponent(split[i + 1]);
                i++;
                continue;
            }

            // Not a recognized prefix, break the loop

            break;
        }

        return i;
    }

    private boolean checkForConstant()
    {

        if (_evaluator.isConstant(_root, _expression))
        {
            _invariant = true;

            _cachedValue = resolveProperty();

            return true;
        }

        return false;
    }

    /**
     * Reassembles the remainder of the split property path from the start point.
     */

    private String reassemble(int start, String[] split)
    {
        int count = split.length - start;

        if (count == 0)
            return null;

        if (count == 1)
            return split[split.length - 1];

        StringBuffer buffer = new StringBuffer();

        for (int i = start; i < split.length; i++)
        {
            if (i > start)
                buffer.append('.');

            buffer.append(split[i]);
        }

        return buffer.toString();
    }

    /**
     * Checks to see if the binding can be converted to an invariant.
     */

    private void checkForInvariant(int start, String[] split)
    {
        // For now, all of our conditions are two properties
        // from a root component.

        if (split.length - start != 2)
            return;

        try
        {
            if (!Ognl.isSimpleNavigationChain(_parsedExpression, getOgnlContext()))
                return;
        }
        catch (OgnlException ex)
        {
            throw new BindingException(
                    Tapestry.format(
                            "ExpressionBinding.unable-to-resolve-expression",
                            _expression,
                            _root),
                    this,
                    ex);
        }

        String first = split[start];

        if (first.equals("listeners"))
        {
            _invariant = true;

            // Could cast to AbstractComponent, get listenersMap, etc.,
            // but this is easier.

            _cachedValue = resolveProperty();
            return;
        }

        if (first.equals("assets"))
        {
            String name = split[start + 1];

            _invariant = true;
            _cachedValue = _root.getAsset(name);
            return;
        }

        if (first.equals("beans"))
        {
            String name = split[start + 1];

            IBeanSpecification bs = _root.getSpecification().getBeanSpecification(name);

            if (bs == null || bs.getLifecycle() != BeanLifecycle.PAGE)
                return;

            // Again, could cast to AbstractComponent, but this
            // is easier.

            _invariant = true;
            _cachedValue = resolveProperty();
            return;
        }

        if (first.equals("bindings"))
        {
            String name = split[start + 1];

            _invariant = true;
            _cachedValue = _root.getBinding(name);
            return;
        }

        // Not a recognized pattern for conversion
        // to invariant.
    }

    /**
     * Updates the property for the binding to the given value.
     *
     * @throws BindingException if the property can't be updated (typically due to an security problem, or a missing
     *                          mutator method).
     * @throws BindingException if the binding is invariant.
     */

    public void setObject(Object value)
    {
        initialize();

        if (_invariant)
            throw createReadOnlyBindingException(this);

        try
        {
            if (_accessor != null)
            {
                _evaluator.write(_root, _accessor, value);
            }
            else if (EXPRESSION_EVALUATION_ENABLED && _evaluator.isCompileEnabled() && _accessor == null)
            {
                //_evaluator.compileExpression(_root, _parsedExpression, _expression);
                //_accessor = _parsedExpression.getAccessor();

                if (!_writeFailed)
                {
                    // re-parse expression as compilation may be possible now that it potentially has a value
                    try
                    {
                        _evaluator.compileExpression(_root, _parsedExpression, _expression);
                        _accessor = _parsedExpression.getAccessor();
                    }
                    catch (Throwable t)
                    {
                        // ignore re-read failures as they aren't supposed to be happening now anyways
                        // and a more user friendly version will be available if someone actually calls
                        // getObject

                        // if writing fails then we're probably screwed...so don't do it again
                        if (value != null)
                            _writeFailed = true;
                    }
                }
            }
            else
            {
                _evaluator.writeCompiled(_root, _parsedExpression, value);
            }
        }
        catch (Throwable ex)
        {
            throw new BindingException(
                    Tapestry.format(
                            "ExpressionBinding.unable-to-update-expression",
                            _expression,
                            _root,
                            value),
                    this,
                    ex);
        }
    }

    /**
     * Returns the a String representing the property path.  This includes the {@link IComponent#getExtendedId()
     * extended id} of the root component and the property path ... once the binding is used, these may change due to
     * optimization of the property path.
     */

    public String toString()
    {
        StringBuffer buffer = new StringBuffer();

        buffer.append("ExpressionBinding[");
        buffer.append(_root.getExtendedId());

        if (_expression != null)
        {
            buffer.append(' ');
            buffer.append(_expression);
        }

        if (_invariant)
        {
            buffer.append(" cachedValue=");
            buffer.append(_cachedValue);
        }

        buffer.append(']');

        return buffer.toString();
    }

}