/*
 * [The "BSD licence"]
 * Copyright (c) 2011 Terence Parr
 * All rights reserved.
 *
 * Conversion to C#:
 * Copyright (c) 2011 Sam Harwell, Pixel Mine, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

namespace Antlr.Runtime.Debug
{
    using ITreeAdaptor = Antlr.Runtime.Tree.ITreeAdaptor;

    /** <summary>
     *  A TreeAdaptor proxy that fires debugging events to a DebugEventListener
     *  delegate and uses the TreeAdaptor delegate to do the actual work.  All
     *  AST events are triggered by this adaptor; no code gen changes are needed
     *  in generated rules.  Debugging events are triggered *after* invoking
     *  tree adaptor routines.
     *  </summary>
     *
     *  <remarks>
     *  Trees created with actions in rewrite actions like "-&gt; ^(ADD {foo} {bar})"
     *  cannot be tracked as they might not use the adaptor to create foo, bar.
     *  The debug listener has to deal with tree node IDs for which it did
     *  not see a createNode event.  A single &lt;unknown&gt; node is sufficient even
     *  if it represents a whole tree.
     *  </remarks>
     */
    public class DebugTreeAdaptor : ITreeAdaptor
    {
        protected IDebugEventListener dbg;
        protected ITreeAdaptor adaptor;

        public DebugTreeAdaptor( IDebugEventListener dbg, ITreeAdaptor adaptor )
        {
            this.dbg = dbg;
            this.adaptor = adaptor;
        }

        public virtual object Create( IToken payload )
        {
            if ( payload.TokenIndex < 0 )
            {
                // could be token conjured up during error recovery
                return Create( payload.Type, payload.Text );
            }
            object node = adaptor.Create( payload );
            dbg.CreateNode( node, payload );
            return node;
        }

        public virtual object ErrorNode( ITokenStream input, IToken start, IToken stop,
                                RecognitionException e )
        {
            object node = adaptor.ErrorNode( input, start, stop, e );
            if ( node != null )
            {
                dbg.ErrorNode( node );
            }
            return node;
        }

        public virtual object DupTree( object tree )
        {
            object t = adaptor.DupTree( tree );
            // walk the tree and emit create and add child events
            // to simulate what dupTree has done. dupTree does not call this debug
            // adapter so I must simulate.
            SimulateTreeConstruction( t );
            return t;
        }

        /** <summary>^(A B C): emit create A, create B, add child, ...</summary> */
        protected virtual void SimulateTreeConstruction( object t )
        {
            dbg.CreateNode( t );
            int n = adaptor.GetChildCount( t );
            for ( int i = 0; i < n; i++ )
            {
                object child = adaptor.GetChild( t, i );
                SimulateTreeConstruction( child );
                dbg.AddChild( t, child );
            }
        }

        public virtual object DupNode( object treeNode )
        {
            object d = adaptor.DupNode( treeNode );
            dbg.CreateNode( d );
            return d;
        }

        public object DupNode(int type, object treeNode)
        {
            object d = adaptor.DupNode(type, treeNode);
            dbg.CreateNode(d);
            return d;
        }

        public object DupNode(object treeNode, string text)
        {
            object d = adaptor.DupNode(treeNode, text);
            dbg.CreateNode(d);
            return d;
        }

        public object DupNode(int type, object treeNode, string text)
        {
            object d = adaptor.DupNode(type, treeNode, text);
            dbg.CreateNode(d);
            return d;
        }

        public virtual object Nil()
        {
            object node = adaptor.Nil();
            dbg.NilNode( node );
            return node;
        }

        public virtual bool IsNil( object tree )
        {
            return adaptor.IsNil( tree );
        }

        public virtual void AddChild( object t, object child )
        {
            if ( t == null || child == null )
            {
                return;
            }
            adaptor.AddChild( t, child );
            dbg.AddChild( t, child );
        }

        public virtual object BecomeRoot( object newRoot, object oldRoot )
        {
            object n = adaptor.BecomeRoot( newRoot, oldRoot );
            dbg.BecomeRoot( newRoot, oldRoot );
            return n;
        }

        public virtual object RulePostProcessing( object root )
        {
            return adaptor.RulePostProcessing( root );
        }

        public virtual void AddChild( object t, IToken child )
        {
            object n = this.Create( child );
            this.AddChild( t, n );
        }

        public virtual object BecomeRoot( IToken newRoot, object oldRoot )
        {
            object n = this.Create( newRoot );
            adaptor.BecomeRoot( n, oldRoot );
            dbg.BecomeRoot( newRoot, oldRoot );
            return n;
        }

        public virtual object Create( int tokenType, IToken fromToken )
        {
            object node = adaptor.Create( tokenType, fromToken );
            dbg.CreateNode( node );
            return node;
        }

        public virtual object Create( int tokenType, IToken fromToken, string text )
        {
            object node = adaptor.Create( tokenType, fromToken, text );
            dbg.CreateNode( node );
            return node;
        }

        public virtual object Create( int tokenType, string text )
        {
            object node = adaptor.Create( tokenType, text );
            dbg.CreateNode( node );
            return node;
        }

        public object Create(IToken fromToken, string text)
        {
            object node = adaptor.Create(fromToken, text);
            dbg.CreateNode(node);
            return node;
        }

        public virtual int GetType( object t )
        {
            return adaptor.GetType( t );
        }

        public virtual void SetType( object t, int type )
        {
            adaptor.SetType( t, type );
        }

        public virtual string GetText( object t )
        {
            return adaptor.GetText( t );
        }

        public virtual void SetText( object t, string text )
        {
            adaptor.SetText( t, text );
        }

        public virtual IToken GetToken( object t )
        {
            return adaptor.GetToken( t );
        }

        public virtual void SetTokenBoundaries( object t, IToken startToken, IToken stopToken )
        {
            adaptor.SetTokenBoundaries( t, startToken, stopToken );
            if ( t != null && startToken != null && stopToken != null )
            {
                dbg.SetTokenBoundaries(
                    t, startToken.TokenIndex,
                    stopToken.TokenIndex );
            }
        }

        public virtual int GetTokenStartIndex( object t )
        {
            return adaptor.GetTokenStartIndex( t );
        }

        public virtual int GetTokenStopIndex( object t )
        {
            return adaptor.GetTokenStopIndex( t );
        }

        public virtual object GetChild( object t, int i )
        {
            return adaptor.GetChild( t, i );
        }

        public virtual void SetChild( object t, int i, object child )
        {
            adaptor.SetChild( t, i, child );
        }

        public virtual object DeleteChild( object t, int i )
        {
            return DeleteChild( t, i );
        }

        public virtual int GetChildCount( object t )
        {
            return adaptor.GetChildCount( t );
        }

        public virtual int GetUniqueID( object node )
        {
            return adaptor.GetUniqueID( node );
        }

        public virtual object GetParent( object t )
        {
            return adaptor.GetParent( t );
        }

        public virtual int GetChildIndex( object t )
        {
            return adaptor.GetChildIndex( t );
        }

        public virtual void SetParent( object t, object parent )
        {
            adaptor.SetParent( t, parent );
        }

        public virtual void SetChildIndex( object t, int index )
        {
            adaptor.SetChildIndex( t, index );
        }

        public virtual void ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t )
        {
            adaptor.ReplaceChildren( parent, startChildIndex, stopChildIndex, t );
        }

        #region support

        public virtual IDebugEventListener GetDebugListener()
        {
            return dbg;
        }

        public virtual void SetDebugListener( IDebugEventListener dbg )
        {
            this.dbg = dbg;
        }

        public virtual ITreeAdaptor GetTreeAdaptor()
        {
            return adaptor;
        }

        #endregion
    }
}
