/*
 * Copyright 2003-2007 the original author or authors.
 *
 * 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.codehaus.groovy.syntax;

import org.codehaus.groovy.GroovyBugError;

import java.io.StringWriter;
import java.io.PrintWriter;


/**
 *  An abstract base class for nodes in the concrete syntax tree that is
 *  the result of parsing.  Note that the CSTNode is inextricably linked
 *  with the Token in that every CSTNode has a Token as it's root.
 *
 *  @see antlr.Parser
 *  @see Token
 *  @see org.codehaus.groovy.syntax.Reduction
 *  @see org.codehaus.groovy.syntax.Types
 *
 *  @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
 *  @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
 *
 *  @version $Id$
 */

public abstract class CSTNode
{

  //---------------------------------------------------------------------------
  // NODE IDENTIFICATION AND MEANING


   /**
    *  Returns the meaning of this node.  If the node isEmpty(), returns
    *  the type of Token.NULL.
    */

    public int getMeaning()
    {
        return getRoot( true ).getMeaning();
    }



   /**
    *  Sets the meaning for this node (and it's root Token).  Not
    *  valid if the node isEmpty().  Returns the node, for convenience.
    */

    public CSTNode setMeaning( int meaning )
    {
        getRoot().setMeaning( meaning );
        return this;
    }



   /**
    *  Returns the actual type of the node.  If the node isEmpty(), returns
    *  the type of Token.NULL.
    */

    public int getType()
    {
        return getRoot( true ).getType();
    }



   /**
    *  Returns true if the node can be coerced to the specified type.
    */

    public boolean canMean( int type )
    {
        return Types.canMean( getMeaning(), type );
    }



   /**
    *  Returns true if the node's meaning matches the specified type.
    */

    public boolean isA( int type )
    {
        return Types.ofType( getMeaning(), type );
    }



   /**
    *  Returns true if the node's meaning matches any of the specified types.
    */

    public boolean isOneOf( int[] types )
    {
        int meaning = getMeaning();
        for( int i = 0; i < types.length; i++ )
        {
            if( Types.ofType(meaning, types[i]) )
            {
                return true;
            }
        }

        return false;
    }



   /**
    *  Returns true if the node's meaning matches all of the specified types.
    */

    public boolean isAllOf( int[] types )
    {
        int meaning = getMeaning();
        for( int i = 0; i < types.length; i++ )
        {
            if( !Types.ofType(meaning, types[i]) )
            {
                return false;
            }
        }

        return true;
    }



   /**
    *  Returns the first matching meaning of the specified types.
    *  Returns Types.UNKNOWN if there are no matches.
    */

    public int getMeaningAs( int[] types )
    {

        for( int i = 0; i < types.length; i++ )
        {
            if( isA(types[i]) )
            {
                return types[i];
            }
        }

        return Types.UNKNOWN;
    }




  //---------------------------------------------------------------------------
  // TYPE SUGAR


   /**
    *  Returns true if the node matches the specified type.  Effectively
    *  a synonym for <code>isA()</code>.  Missing nodes are Token.NULL.
    */

    boolean matches( int type )
    {
        return isA(type);
    }



   /**
    *  Returns true if the node and it's first child match the specified
    *  types.  Missing nodes are Token.NULL.
    */

    boolean matches( int type, int child1 )
    {
        return isA(type) && get(1, true).isA(child1);
    }



   /**
    *  Returns true if the node and it's first and second child match the
    *  specified types.  Missing nodes are Token.NULL.
    */

    boolean matches( int type, int child1, int child2 )
    {
        return matches( type, child1 ) && get(2, true).isA(child2);
    }



   /**
    *  Returns true if the node and it's first three children match the
    *  specified types.  Missing nodes are Token.NULL.
    */

    boolean matches( int type, int child1, int child2, int child3 )
    {
        return matches( type, child1, child2 ) && get(3, true).isA(child3);
    }



   /**
    *  Returns true if the node an it's first four children match the
    *  specified types.  Missing nodes have type Types.NULL.
    */

    boolean matches( int type, int child1, int child2, int child3, int child4 )
    {
        return matches( type, child1, child2, child3 ) && get(4, true).isA(child4);
    }





  //---------------------------------------------------------------------------
  // MEMBER ACCESS


   /**
    *  Returns true if the node is completely empty (no root, even).
    */

    public boolean isEmpty()
    {
        return false;
    }



   /**
    *  Returns the number of elements in the node (including root).
    */

    public abstract int size();



   /**
    *  Returns true if the node has any non-root elements.
    */

    public boolean hasChildren()
    {
        return children() > 0;
    }



   /**
    *  Returns the number of non-root elements in the node.
    */

    public int children()
    {
        int size = size();
        if( size > 1 )
        {
            return size - 1;
        }
        return 0;
    }



   /**
    *  Returns the specified element, or null.
    */

    public abstract CSTNode get( int index );



   /**
    *  Returns the specified element, or Token.NULL if
    *  safe is set and the specified element is null (or doesn't
    *  exist).
    */

    public CSTNode get( int index, boolean safe )
    {
        CSTNode element = get( index );

        if( element == null && safe )
        {
            element = Token.NULL;
        }

        return element;
    }



   /**
    *  Returns the root of the node.  By convention, all nodes have
    *  a Token as the first element (or root), which indicates the type
    *  of the node.  May return null if the node <code>isEmpty()</code>.
    */

    public abstract Token getRoot();



   /**
    *  Returns the root of the node, the Token that indicates it's
    *  type.  Returns a Token.NULL if safe and the actual root is null.
    */

    public Token getRoot( boolean safe )
    {
        Token root = getRoot();

        if( root == null && safe )
        {
            root = Token.NULL;
        }

        return root;
    }



   /**
    *  Returns the text of the root.  Uses <code>getRoot(true)</code>
    *  to get the root, so you will only receive null in return if the
    *  root token returns it.
    */

    public String getRootText()
    {
        Token root = getRoot( true );
        return root.getText();
    }



   /**
    *  Returns a description of the node.
    */

    public String getDescription()
    {
        return Types.getDescription( getMeaning() );
    }



   /**
    *  Returns the starting line of the node.  Returns -1
    *  if not known.
    */

    public int getStartLine()
    {
        return getRoot(true).getStartLine();
    }



   /**
    *  Returns the starting column of the node.  Returns -1
    *  if not known.
    */

    public int getStartColumn()
    {
        return getRoot(true).getStartColumn();
    }



   /**
    *  Marks the node a complete expression.  Not all nodes support
    *  this operation!
    */

    public void markAsExpression()
    {
        throw new GroovyBugError( "markAsExpression() not supported for this CSTNode type" );
    }



   /**
    *  Returns true if the node is a complete expression.
    */

    public boolean isAnExpression()
    {
        return isA(Types.SIMPLE_EXPRESSION);
    }





  //---------------------------------------------------------------------------
  // OPERATIONS


   /**
    *  Adds an element to the node.  Returns the element for convenience.
    *  Not all nodes support this operation!
    */

    public CSTNode add( CSTNode element )
    {
        throw new GroovyBugError( "add() not supported for this CSTNode type" );
    }



   /**
    *  Adds all children of the specified node to this one.  Not all
    *  nodes support this operation!
    */

    public void addChildrenOf( CSTNode of )
    {
        for( int i = 1; i < of.size(); i++ )
        {
            add( of.get(i) );
        }
    }



   /**
    *  Sets an element node in at the specified index.  Returns the element
    *  for convenience.  Not all nodes support this operation!
    */

    public CSTNode set( int index, CSTNode element )
    {
        throw new GroovyBugError( "set() not supported for this CSTNode type" );
    }



   /**
    *  Creates a <code>Reduction</code> from this node.  Returns self if the
    *  node is already a <code>Reduction</code>.
    */

    public abstract Reduction asReduction();




  //---------------------------------------------------------------------------
  // STRING CONVERSION


   /**
    *  Formats the node as a <code>String</code> and returns it.
    */

    public String toString()
    {
        StringWriter string = new StringWriter();
        write( new PrintWriter(string) );

        string.flush();
        return string.toString();
    }


   /**
    *  Formats the node and writes it to the specified <code>Writer</code>.
    */

    public void write( PrintWriter writer )
    {
        write( writer, "" );
    }


   /**
    *  Formats the node and writes it to the specified <code>Writer</code>.
    *  The indent is prepended to each output line, and is increased for each
    *  recursion.
    */

    protected void write( PrintWriter writer, String indent )
    {
        writer.print( "(" );

        if( !isEmpty() )
        {
            Token  root = getRoot( true );
            int    type = root.getType();
            int meaning = root.getMeaning();


            //
            // Display our type, text, and (optional) meaning

            writer.print( Types.getDescription(type) );

            if( meaning != type )
            {
                writer.print( " as " );
                writer.print( Types.getDescription(meaning) );
            }

            if( getStartLine() > -1 )
            {
                writer.print( " at " + getStartLine() + ":" + getStartColumn() );
            }

            String text = root.getText();
            int  length = text.length();
            if( length > 0 )
            {
                writer.print( ": " );
                if( length > 40 )
                {
                   text = text.substring( 0, 17 ) + "..." + text.substring( length - 17, length );
                }

                writer.print( " \"" );
                writer.print( text );
                writer.print( "\" " );
            }
            else if( children() > 0 )
            {
                writer.print( ": " );
            }



            //
            // Recurse to display the children.

            int count = size();
            if( count > 1 )
            {
                writer.println( "" );

                String indent1 = indent + "  ";
                String indent2 = indent + "   ";
                for( int i = 1; i < count; i++ )
                {
                    writer.print( indent1 );
                    writer.print( i );
                    writer.print( ": " );

                    get( i, true ).write( writer, indent2 );
                }

                writer.print( indent );
            }
        }

        if( indent.length() > 0 )
        {
            writer.println( ")" );
        }
        else
        {
            writer.print( ")" );
        }
    }
}
