/*
 * [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.Debug
{
    using System.Collections.Generic;
    using ParseTree = Antlr.Runtime.Tree.ParseTree;

    /** <summary>
     *  This parser listener tracks rule entry/exit and token matches
     *  to build a simple parse tree using ParseTree nodes.
     *  </summary>
     */
    public class ParseTreeBuilder : BlankDebugEventListener
    {
        public const string EPSILON_PAYLOAD = "<epsilon>";

        Stack<ParseTree> callStack = new Stack<ParseTree>();
        List<IToken> hiddenTokens = new List<IToken>();
        int backtracking = 0;

        public ParseTreeBuilder( string grammarName )
        {
            ParseTree root = Create( "<grammar " + grammarName + ">" );
            callStack.Push( root );
        }

        public virtual ParseTree Tree
        {
            get
            {
                ParseTree[] stack = callStack.ToArray();
                return stack[stack.Length - 1];
            }
        }

        /** <summary>
         *  What kind of node to create.  You might want to override
         *  so I factored out creation here.
         *  </summary>
         */
        public virtual ParseTree Create( object payload )
        {
            return new ParseTree( payload );
        }

        public virtual ParseTree EpsilonNode()
        {
            return Create( EPSILON_PAYLOAD );
        }

        /** <summary>Backtracking or cyclic DFA, don't want to add nodes to tree</summary> */
        public override void EnterDecision( int d, bool couldBacktrack )
        {
            backtracking++;
        }
        public override void ExitDecision( int i )
        {
            backtracking--;
        }

        public override void EnterRule( string filename, string ruleName )
        {
            if ( backtracking > 0 )
                return;
            ParseTree parentRuleNode = callStack.Peek();
            ParseTree ruleNode = Create( ruleName );
            parentRuleNode.AddChild( ruleNode );
            callStack.Push( ruleNode );
        }

        public override void ExitRule( string filename, string ruleName )
        {
            if ( backtracking > 0 )
                return;
            ParseTree ruleNode = callStack.Peek();
            if ( ruleNode.ChildCount == 0 )
            {
                ruleNode.AddChild( EpsilonNode() );
            }
            callStack.Pop();
        }

        public override void ConsumeToken( IToken token )
        {
            if ( backtracking > 0 )
                return;
            ParseTree ruleNode = callStack.Peek();
            ParseTree elementNode = Create( token );
            elementNode.hiddenTokens = this.hiddenTokens;
            this.hiddenTokens = new List<IToken>();
            ruleNode.AddChild( elementNode );
        }

        public override void ConsumeHiddenToken( IToken token )
        {
            if ( backtracking > 0 )
                return;
            hiddenTokens.Add( token );
        }

        public override void RecognitionException( RecognitionException e )
        {
            if ( backtracking > 0 )
                return;
            ParseTree ruleNode = callStack.Peek();
            ParseTree errorNode = Create( e );
            ruleNode.AddChild( errorNode );
        }
    }
}
