package org.apache.commons.ognl;

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

import org.apache.commons.ognl.enhance.ExpressionAccessor;

import java.io.PrintWriter;
import java.io.Serializable;

public abstract class SimpleNode
    implements Node, Serializable
{

    private static final long serialVersionUID = 8305393337889433901L;

    protected Node parent;

    protected Node[] children;

    protected int id;

    protected OgnlParser parser;

    private boolean constantValueCalculated;

    private volatile boolean hasConstantValue;

    private Object constantValue;

    private ExpressionAccessor accessor;

    public SimpleNode( int i )
    {
        id = i;
    }

    public SimpleNode( OgnlParser p, int i )
    {
        this( i );
        parser = p;
    }

    public void jjtOpen()
    {
    }

    public void jjtClose()
    {
    }

    public void jjtSetParent( Node n )
    {
        parent = n;
    }

    public Node jjtGetParent()
    {
        return parent;
    }

    public void jjtAddChild( Node n, int i )
    {
        if ( children == null )
        {
            children = new Node[i + 1];
        }
        else if ( i >= children.length )
        {
            Node c[] = new Node[i + 1];
            System.arraycopy( children, 0, c, 0, children.length );
            children = c;
        }
        children[i] = n;
    }

    public Node jjtGetChild( int i )
    {
        return children[i];
    }

    public int jjtGetNumChildren()
    {
        return ( children == null ) ? 0 : children.length;
    }

    /*
     * You can override these two methods in subclasses of SimpleNode to customize the way the node appears when the
     * tree is dumped. If your output uses more than one line you should override toString(String), otherwise overriding
     * toString() is probably all you need to do.
     */

    @Override
    public String toString()
    {
        final StringBuilder data = new StringBuilder();
        try
        {
            accept( ToStringVisitor.INSTANCE, data );
        }
        catch ( OgnlException e )
        {
            // ignored.
        }
        return data.toString();
    }

    // OGNL additions

    public String toString( String prefix )
    {
        return prefix + OgnlParserTreeConstants.jjtNodeName[id] + " " + toString();
    }

    public String toGetSourceString( OgnlContext context, Object target )
    {
        return toString();
    }

    public String toSetSourceString( OgnlContext context, Object target )
    {
        return toString();
    }

    /*
     * Override this method if you want to customize how the node dumps out its children.
     */

    public void dump( PrintWriter writer, String prefix )
    {
        writer.println( toString( prefix ) );

        if ( children != null )
        {
            for ( int i = 0; i < children.length; ++i )
            {
                SimpleNode n = (SimpleNode) children[i];
                if ( n != null )
                {
                    n.dump( writer, prefix + "  " );
                }
            }
        }
    }

    public int getIndexInParent()
    {
        int result = -1;

        if ( parent != null )
        {
            int icount = parent.jjtGetNumChildren();

            for ( int i = 0; i < icount; i++ )
            {
                if ( parent.jjtGetChild( i ) == this )
                {
                    result = i;
                    break;
                }
            }
        }

        return result;
    }

    public Node getNextSibling()
    {
        Node result = null;
        int i = getIndexInParent();

        if ( i >= 0 )
        {
            int icount = parent.jjtGetNumChildren();

            if ( i < icount )
            {
                result = parent.jjtGetChild( i + 1 );
            }
        }
        return result;
    }

    protected Object evaluateGetValueBody( OgnlContext context, Object source )
        throws OgnlException
    {
        context.setCurrentObject( source );
        context.setCurrentNode( this );

        if ( !constantValueCalculated )
        {
            constantValueCalculated = true;
            boolean constant = isConstant( context );

            if ( constant )
            {
                constantValue = getValueBody( context, source );
            }

            hasConstantValue = constant;
        }

        return hasConstantValue ? constantValue : getValueBody( context, source );
    }

    protected void evaluateSetValueBody( OgnlContext context, Object target, Object value )
        throws OgnlException
    {
        context.setCurrentObject( target );
        context.setCurrentNode( this );
        setValueBody( context, target, value );
    }

    public final Object getValue( OgnlContext context, Object source )
        throws OgnlException
    {
        Object result = null;

        if ( context.getTraceEvaluations() )
        {

            Throwable evalException = null;
            Evaluation evaluation = new Evaluation( this, source );

            context.pushEvaluation( evaluation );
            try
            {
                result = evaluateGetValueBody( context, source );
            }
            catch ( OgnlException ex )
            {
                evalException = ex;
                throw ex;
            }
            catch ( RuntimeException ex )
            {
                evalException = ex;
                throw ex;
            }
            finally
            {
                Evaluation eval = context.popEvaluation();

                eval.setResult( result );
                if ( evalException != null )
                {
                    eval.setException( evalException );
                }
            }
        }
        else
        {
            result = evaluateGetValueBody( context, source );
        }

        return result;
    }

    /**
     * Subclasses implement this method to do the actual work of extracting the appropriate value from the source
     * object.
     */
    protected abstract Object getValueBody( OgnlContext context, Object source )
        throws OgnlException;

    public final void setValue( OgnlContext context, Object target, Object value )
        throws OgnlException
    {
        if ( context.getTraceEvaluations() )
        {
            Throwable evalException = null;
            Evaluation evaluation = new Evaluation( this, target, true );

            context.pushEvaluation( evaluation );
            try
            {
                evaluateSetValueBody( context, target, value );
            }
            catch ( OgnlException ex )
            {
                evalException = ex;
                ex.setEvaluation( evaluation );
                throw ex;
            }
            catch ( RuntimeException ex )
            {
                evalException = ex;
                throw ex;
            }
            finally
            {
                Evaluation eval = context.popEvaluation();

                if ( evalException != null )
                {
                    eval.setException( evalException );
                }
            }
        }
        else
        {
            evaluateSetValueBody( context, target, value );
        }
    }

    /**
     * Subclasses implement this method to do the actual work of setting the appropriate value in the target object. The
     * default implementation throws an <code>InappropriateExpressionException</code>, meaning that it cannot be a set
     * expression.
     */
    protected void setValueBody( OgnlContext context, Object target, Object value )
        throws OgnlException
    {
        throw new InappropriateExpressionException( this );
    }

    /** Returns true iff this node is constant without respect to the children. */
    public boolean isNodeConstant( OgnlContext context )
        throws OgnlException
    {
        return false;
    }

    public boolean isConstant( OgnlContext context )
        throws OgnlException
    {
        return isNodeConstant( context );
    }

    public boolean isNodeSimpleProperty( OgnlContext context )
        throws OgnlException
    {
        return false;
    }

    public boolean isSimpleProperty( OgnlContext context )
        throws OgnlException
    {
        return isNodeSimpleProperty( context );
    }

    public boolean isSimpleNavigationChain( OgnlContext context )
        throws OgnlException
    {
        return isSimpleProperty( context );
    }

    public boolean isEvalChain( OgnlContext context )
        throws OgnlException
    {
        if ( children == null )
        {
            return false;
        }
        for ( Node child : children )
        {
            if ( child instanceof SimpleNode && ( (SimpleNode) child ).isEvalChain( context ) )
            {
                return true;
            }

        }
        return false;
    }

    protected boolean lastChild( OgnlContext context )
    {
        return parent == null || context.get( "_lastChild" ) != null;
    }

    /**
     * This method may be called from subclasses' jjtClose methods. It flattens the tree under this node by eliminating
     * any children that are of the same class as this node and copying their children to this node.
     */
    protected void flattenTree()
    {
        boolean shouldFlatten = false;
        int newSize = 0;

        for ( Node aChildren : children )
        {
            if ( aChildren.getClass() == getClass() )
            {
                shouldFlatten = true;
                newSize += aChildren.jjtGetNumChildren();
            }
            else
            {
                ++newSize;
            }
        }

        if ( shouldFlatten )
        {
            Node[] newChildren = new Node[newSize];
            int j = 0;

            for ( Node c : children )
            {
                if ( c.getClass() == getClass() )
                {
                    for ( int k = 0; k < c.jjtGetNumChildren(); ++k )
                    {
                        newChildren[j++] = c.jjtGetChild( k );
                    }

                }
                else
                {
                    newChildren[j++] = c;
                }
            }

            if ( j != newSize )
            {
                throw new Error( "Assertion error: " + j + " != " + newSize );
            }

            children = newChildren;
        }
    }

    public ExpressionAccessor getAccessor()
    {
        return accessor;
    }

    public void setAccessor( ExpressionAccessor accessor )
    {
        this.accessor = accessor;
    }
}
