﻿/*
 * [The "BSD licence"]
 * Copyright (c) 2005-2008 Terence Parr
 * All rights reserved.
 *
 * Conversion to C#:
 * Copyright (c) 2008-2009 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.Tree
{
    using System.Collections.Generic;

    using Console = System.Console;
    using IList = System.Collections.IList;
    using InvalidOperationException = System.InvalidOperationException;
    using StringBuilder = System.Text.StringBuilder;

    /** <summary>A buffered stream of tree nodes.  Nodes can be from a tree of ANY kind.</summary>
     *
     *  This node stream sucks all nodes out of the tree specified in
     *  the constructor during construction and makes pointers into
     *  the tree using an array of Object pointers. The stream necessarily
     *  includes pointers to DOWN and UP and EOF nodes.
     *
     *  This stream knows how to mark/release for backtracking.
     *
     *  This stream is most suitable for tree interpreters that need to
     *  jump around a lot or for tree parsers requiring speed (at cost of memory).
     *  There is some duplicated functionality here with UnBufferedTreeNodeStream
     *  but just in bookkeeping, not tree walking etc...
     *
     *  TARGET DEVELOPERS:
     *
     *  This is the old CommonTreeNodeStream that buffered up entire node stream.
     *  No need to implement really as new CommonTreeNodeStream is much better
     *  and covers what we need.
     *
     *  @see CommonTreeNodeStream
     */
    public class BufferedTreeNodeStream : ITreeNodeStream, ITokenStreamInformation
    {
        public const int DEFAULT_INITIAL_BUFFER_SIZE = 100;
        public const int INITIAL_CALL_STACK_SIZE = 10;

        protected sealed class StreamIterator : IEnumerator<object>
        {
            BufferedTreeNodeStream _outer;
            int _index;

            public StreamIterator( BufferedTreeNodeStream outer )
            {
                _outer = outer;
                _index = -1;
            }

            #region IEnumerator<object> Members

            public object Current
            {
                get
                {
                    if ( _index < _outer.nodes.Count )
                        return _outer.nodes[_index];

                    return _outer.eof;
                }
            }

            #endregion

            #region IDisposable Members

            public void Dispose()
            {
            }

            #endregion

            #region IEnumerator Members

            public bool MoveNext()
            {
                if ( _index < _outer.nodes.Count )
                    _index++;

                return _index < _outer.nodes.Count;
            }

            public void Reset()
            {
                _index = -1;
            }

            #endregion
        }

        // all these navigation nodes are shared and hence they
        // cannot contain any line/column info

        protected object down;
        protected object up;
        protected object eof;

        /** <summary>The complete mapping from stream index to tree node.
         *  This buffer includes pointers to DOWN, UP, and EOF nodes.
         *  It is built upon ctor invocation.  The elements are type
         *  Object as we don't what the trees look like.</summary>
         *
         *  Load upon first need of the buffer so we can set token types
         *  of interest for reverseIndexing.  Slows us down a wee bit to
         *  do all of the if p==-1 testing everywhere though.
         */
        protected IList nodes;

        /** <summary>Pull nodes from which tree?</summary> */
        protected object root;

        /** <summary>IF this tree (root) was created from a token stream, track it.</summary> */
        protected ITokenStream tokens;

        /** <summary>What tree adaptor was used to build these trees</summary> */
        ITreeAdaptor adaptor;

        /** <summary>Reuse same DOWN, UP navigation nodes unless this is true</summary> */
        bool uniqueNavigationNodes = false;

        /** <summary>The index into the nodes list of the current node (next node
         *  to consume).  If -1, nodes array not filled yet.</summary>
         */
        protected int p = -1;

        /** <summary>Track the last mark() call result value for use in rewind().</summary> */
        protected int lastMarker;

        /** <summary>Stack of indexes used for push/pop calls</summary> */
        protected Stack<int> calls;

        public BufferedTreeNodeStream( object tree )
            : this( new CommonTreeAdaptor(), tree )
        {
        }

        public BufferedTreeNodeStream( ITreeAdaptor adaptor, object tree )
            : this( adaptor, tree, DEFAULT_INITIAL_BUFFER_SIZE )
        {
        }

        public BufferedTreeNodeStream( ITreeAdaptor adaptor, object tree, int initialBufferSize )
        {
            this.root = tree;
            this.adaptor = adaptor;
            nodes = new List<object>( initialBufferSize );
            down = adaptor.Create( TokenTypes.Down, "DOWN" );
            up = adaptor.Create( TokenTypes.Up, "UP" );
            eof = adaptor.Create( TokenTypes.EndOfFile, "EOF" );
        }

        #region Properties

        public virtual int Count
        {
            get
            {
                if ( p == -1 )
                {
                    throw new InvalidOperationException( "Cannot determine the Count before the buffer is filled." );
                }
                return nodes.Count;
            }
        }

        public virtual object TreeSource
        {
            get
            {
                return root;
            }
        }

        public virtual string SourceName
        {
            get
            {
                return TokenStream.SourceName;
            }
        }

        public virtual ITokenStream TokenStream
        {
            get
            {
                return tokens;
            }
            set
            {
                tokens = value;
            }
        }

        public virtual ITreeAdaptor TreeAdaptor
        {
            get
            {
                return adaptor;
            }
            set
            {
                adaptor = value;
            }
        }

        public virtual bool UniqueNavigationNodes
        {
            get
            {
                return uniqueNavigationNodes;
            }
            set
            {
                uniqueNavigationNodes = value;
            }
        }

        public virtual IToken LastToken
        {
            get
            {
                return TreeAdaptor.GetToken(LB(1));
            }
        }

        public virtual IToken LastRealToken
        {
            get
            {
                int i = 0;
                IToken token;
                do
                {
                    i++;
                    token = TreeAdaptor.GetToken(LB(i));
                } while (token != null && token.Line <= 0);

                return token;
            }
        }

        public virtual int MaxLookBehind
        {
            get
            {
                return int.MaxValue;
            }
        }

        #endregion

        /** Walk tree with depth-first-search and fill nodes buffer.
         *  Don't do DOWN, UP nodes if its a list (t is isNil).
         */
        protected virtual void FillBuffer()
        {
            FillBuffer( root );
            //Console.Out.WriteLine( "revIndex=" + tokenTypeToStreamIndexesMap );
            p = 0; // buffer of nodes intialized now
        }

        public virtual void FillBuffer( object t )
        {
            bool nil = adaptor.IsNil( t );
            if ( !nil )
            {
                nodes.Add( t ); // add this node
            }
            // add DOWN node if t has children
            int n = adaptor.GetChildCount( t );
            if ( !nil && n > 0 )
            {
                AddNavigationNode( TokenTypes.Down );
            }
            // and now add all its children
            for ( int c = 0; c < n; c++ )
            {
                object child = adaptor.GetChild( t, c );
                FillBuffer( child );
            }
            // add UP node if t has children
            if ( !nil && n > 0 )
            {
                AddNavigationNode( TokenTypes.Up );
            }
        }

        /** What is the stream index for node? 0..n-1
         *  Return -1 if node not found.
         */
        protected virtual int GetNodeIndex( object node )
        {
            if ( p == -1 )
            {
                FillBuffer();
            }
            for ( int i = 0; i < nodes.Count; i++ )
            {
                object t = nodes[i];
                if ( t == node )
                {
                    return i;
                }
            }
            return -1;
        }

        /** As we flatten the tree, we use UP, DOWN nodes to represent
         *  the tree structure.  When debugging we need unique nodes
         *  so instantiate new ones when uniqueNavigationNodes is true.
         */
        protected virtual void AddNavigationNode( int ttype )
        {
            object navNode = null;
            if ( ttype == TokenTypes.Down )
            {
                if ( UniqueNavigationNodes )
                {
                    navNode = adaptor.Create( TokenTypes.Down, "DOWN" );
                }
                else
                {
                    navNode = down;
                }
            }
            else
            {
                if ( UniqueNavigationNodes )
                {
                    navNode = adaptor.Create( TokenTypes.Up, "UP" );
                }
                else
                {
                    navNode = up;
                }
            }
            nodes.Add( navNode );
        }

        public virtual object this[int i]
        {
            get
            {
                if ( p == -1 )
                {
                    throw new InvalidOperationException( "Cannot get the node at index i before the buffer is filled." );
                }
                return nodes[i];
            }
        }

        public virtual object LT( int k )
        {
            if ( p == -1 )
            {
                FillBuffer();
            }
            if ( k == 0 )
            {
                return null;
            }
            if ( k < 0 )
            {
                return LB( -k );
            }
            //System.out.print("LT(p="+p+","+k+")=");
            if ( ( p + k - 1 ) >= nodes.Count )
            {
                return eof;
            }
            return nodes[p + k - 1];
        }

        public virtual object GetCurrentSymbol()
        {
            return LT( 1 );
        }

#if false
        public virtual object getLastTreeNode()
        {
            int i = Index;
            if ( i >= size() )
            {
                i--; // if at EOF, have to start one back
            }
            Console.Out.WriteLine( "start last node: " + i + " size==" + nodes.Count );
            while ( i >= 0 &&
                ( adaptor.getType( this[i] ) == TokenTypes.EOF ||
                 adaptor.getType( this[i] ) == TokenTypes.UP ||
                 adaptor.getType( this[i] ) == TokenTypes.DOWN ) )
            {
                i--;
            }
            Console.Out.WriteLine( "stop at node: " + i + " " + nodes[i] );
            return nodes[i];
        }
#endif

        /** <summary>Look backwards k nodes</summary> */
        protected virtual object LB( int k )
        {
            if ( k == 0 )
            {
                return null;
            }
            if ( ( p - k ) < 0 )
            {
                return null;
            }
            return nodes[p - k];
        }

        public virtual void Consume()
        {
            if ( p == -1 )
            {
                FillBuffer();
            }
            p++;
        }

        public virtual int LA( int i )
        {
            return adaptor.GetType( LT( i ) );
        }

        public virtual int Mark()
        {
            if ( p == -1 )
            {
                FillBuffer();
            }
            lastMarker = Index;
            return lastMarker;
        }

        public virtual void Release( int marker )
        {
            // no resources to release
        }

        public virtual int Index
        {
            get
            {
                return p;
            }
        }

        public virtual void Rewind( int marker )
        {
            Seek( marker );
        }

        public virtual void Rewind()
        {
            Seek( lastMarker );
        }

        public virtual void Seek( int index )
        {
            if ( p == -1 )
            {
                FillBuffer();
            }
            p = index;
        }

        /** <summary>
         *  Make stream jump to a new location, saving old location.
         *  Switch back with pop().
         *  </summary>
         */
        public virtual void Push( int index )
        {
            if ( calls == null )
            {
                calls = new Stack<int>();
            }
            calls.Push( p ); // save current index
            Seek( index );
        }

        /** <summary>
         *  Seek back to previous index saved during last push() call.
         *  Return top of stack (return index).
         *  </summary>
         */
        public virtual int Pop()
        {
            int ret = calls.Pop();
            Seek( ret );
            return ret;
        }

        public virtual void Reset()
        {
            p = 0;
            lastMarker = 0;
            if ( calls != null )
            {
                calls.Clear();
            }
        }

        public virtual IEnumerator<object> Iterator()
        {
            if ( p == -1 )
            {
                FillBuffer();
            }

            return new StreamIterator( this );
        }

        // TREE REWRITE INTERFACE

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

        /** <summary>Used for testing, just return the token type stream</summary> */
        public virtual string ToTokenTypeString()
        {
            if ( p == -1 )
            {
                FillBuffer();
            }
            StringBuilder buf = new StringBuilder();
            for ( int i = 0; i < nodes.Count; i++ )
            {
                object t = nodes[i];
                buf.Append( " " );
                buf.Append( adaptor.GetType( t ) );
            }
            return buf.ToString();
        }

        /** <summary>Debugging</summary> */
        public virtual string ToTokenString( int start, int stop )
        {
            if ( p == -1 )
            {
                FillBuffer();
            }
            StringBuilder buf = new StringBuilder();
            for ( int i = start; i < nodes.Count && i <= stop; i++ )
            {
                object t = nodes[i];
                buf.Append( " " );
                buf.Append( adaptor.GetToken( t ) );
            }
            return buf.ToString();
        }

        public virtual string ToString( object start, object stop )
        {
            Console.Out.WriteLine( "toString" );
            if ( start == null || stop == null )
            {
                return null;
            }
            if ( p == -1 )
            {
                throw new InvalidOperationException( "Buffer is not yet filled." );
            }
            //Console.Out.WriteLine( "stop: " + stop );
            if ( start is CommonTree )
                Console.Out.Write( "toString: " + ( (CommonTree)start ).Token + ", " );
            else
                Console.Out.WriteLine( start );
            if ( stop is CommonTree )
                Console.Out.WriteLine( ( (CommonTree)stop ).Token );
            else
                Console.Out.WriteLine( stop );
            // if we have the token stream, use that to dump text in order
            if ( tokens != null )
            {
                int beginTokenIndex = adaptor.GetTokenStartIndex( start );
                int endTokenIndex = adaptor.GetTokenStopIndex( stop );
                // if it's a tree, use start/stop index from start node
                // else use token range from start/stop nodes
                if ( adaptor.GetType( stop ) == TokenTypes.Up )
                {
                    endTokenIndex = adaptor.GetTokenStopIndex( start );
                }
                else if ( adaptor.GetType( stop ) == TokenTypes.EndOfFile )
                {
                    endTokenIndex = Count - 2; // don't use EOF
                }
                return tokens.ToString( beginTokenIndex, endTokenIndex );
            }
            // walk nodes looking for start
            object t = null;
            int i = 0;
            for ( ; i < nodes.Count; i++ )
            {
                t = nodes[i];
                if ( t == start )
                {
                    break;
                }
            }
            // now walk until we see stop, filling string buffer with text
            StringBuilder buf = new StringBuilder();
            t = nodes[i];
            while ( t != stop )
            {
                string text = adaptor.GetText( t );
                if ( text == null )
                {
                    text = " " + adaptor.GetType( t ).ToString();
                }
                buf.Append( text );
                i++;
                t = nodes[i];
            }
            // include stop node too
            string text2 = adaptor.GetText( stop );
            if ( text2 == null )
            {
                text2 = " " + adaptor.GetType( stop ).ToString();
            }
            buf.Append( text2 );
            return buf.ToString();
        }
    }
}
