/*
 * [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
{
    using ConditionalAttribute = System.Diagnostics.ConditionalAttribute;
    using Console = System.Console;
    using IDebugEventListener = Antlr.Runtime.Debug.IDebugEventListener;

    public delegate int SpecialStateTransitionHandler( DFA dfa, int s, IIntStream input );

    /** <summary>A DFA implemented as a set of transition tables.</summary>
     *
     *  <remarks>
     *  Any state that has a semantic predicate edge is special; those states
     *  are generated with if-then-else structures in a specialStateTransition()
     *  which is generated by cyclicDFA template.
     *
     *  There are at most 32767 states (16-bit signed short).
     *  Could get away with byte sometimes but would have to generate different
     *  types and the simulation code too.  For a point of reference, the Java
     *  lexer's Tokens rule DFA has 326 states roughly.
     *  </remarks>
     */
    public class DFA
    {
        protected short[] eot;
        protected short[] eof;
        protected char[] min;
        protected char[] max;
        protected short[] accept;
        protected short[] special;
        protected short[][] transition;

        protected int decisionNumber;

        /** <summary>Which recognizer encloses this DFA?  Needed to check backtracking</summary> */
        protected BaseRecognizer recognizer;

        public readonly bool debug = false;

        public DFA()
            : this( new SpecialStateTransitionHandler( SpecialStateTransitionDefault ) )
        {
        }

        public DFA( SpecialStateTransitionHandler specialStateTransition )
        {
            this.SpecialStateTransition = specialStateTransition ?? new SpecialStateTransitionHandler( SpecialStateTransitionDefault );
        }

        public virtual string Description
        {
            get
            {
                return "n/a";
            }
        }

        /** <summary>
         *  From the input stream, predict what alternative will succeed
         *  using this DFA (representing the covering regular approximation
         *  to the underlying CFL).  Return an alternative number 1..n.  Throw
         *  an exception upon error.
         *  </summary>
         */
        public virtual int Predict( IIntStream input )
        {
            if ( debug )
            {
                Console.Error.WriteLine( "Enter DFA.predict for decision " + decisionNumber );
            }
            int mark = input.Mark(); // remember where decision started in input
            int s = 0; // we always start at s0
            try
            {
                for ( ; ; )
                {
                    if ( debug )
                        Console.Error.WriteLine( "DFA " + decisionNumber + " state " + s + " LA(1)=" + (char)input.LA( 1 ) + "(" + input.LA( 1 ) +
                                           "), index=" + input.Index );
                    int specialState = special[s];
                    if ( specialState >= 0 )
                    {
                        if ( debug )
                        {
                            Console.Error.WriteLine( "DFA " + decisionNumber +
                                " state " + s + " is special state " + specialState );
                        }
                        s = SpecialStateTransition( this, specialState, input );
                        if ( debug )
                        {
                            Console.Error.WriteLine( "DFA " + decisionNumber +
                                " returns from special state " + specialState + " to " + s );
                        }
                        if ( s == -1 )
                        {
                            NoViableAlt( s, input );
                            return 0;
                        }
                        input.Consume();
                        continue;
                    }
                    if ( accept[s] >= 1 )
                    {
                        if ( debug )
                            Console.Error.WriteLine( "accept; predict " + accept[s] + " from state " + s );
                        return accept[s];
                    }
                    // look for a normal char transition
                    char c = (char)input.LA( 1 ); // -1 == \uFFFF, all tokens fit in 65000 space
                    if ( c >= min[s] && c <= max[s] )
                    {
                        int snext = transition[s][c - min[s]]; // move to next state
                        if ( snext < 0 )
                        {
                            // was in range but not a normal transition
                            // must check EOT, which is like the else clause.
                            // eot[s]>=0 indicates that an EOT edge goes to another
                            // state.
                            if ( eot[s] >= 0 )
                            {  // EOT Transition to accept state?
                                if ( debug )
                                    Console.Error.WriteLine( "EOT transition" );
                                s = eot[s];
                                input.Consume();
                                // TODO: I had this as return accept[eot[s]]
                                // which assumed here that the EOT edge always
                                // went to an accept...faster to do this, but
                                // what about predicated edges coming from EOT
                                // target?
                                continue;
                            }
                            NoViableAlt( s, input );
                            return 0;
                        }
                        s = snext;
                        input.Consume();
                        continue;
                    }
                    if ( eot[s] >= 0 )
                    {  // EOT Transition?
                        if ( debug )
                            Console.Error.WriteLine( "EOT transition" );
                        s = eot[s];
                        input.Consume();
                        continue;
                    }
                    if ( c == unchecked( (char)TokenTypes.EndOfFile ) && eof[s] >= 0 )
                    {  // EOF Transition to accept state?
                        if ( debug )
                            Console.Error.WriteLine( "accept via EOF; predict " + accept[eof[s]] + " from " + eof[s] );
                        return accept[eof[s]];
                    }
                    // not in range and not EOF/EOT, must be invalid symbol
                    if ( debug )
                    {
                        Console.Error.WriteLine( "min[" + s + "]=" + min[s] );
                        Console.Error.WriteLine( "max[" + s + "]=" + max[s] );
                        Console.Error.WriteLine( "eot[" + s + "]=" + eot[s] );
                        Console.Error.WriteLine( "eof[" + s + "]=" + eof[s] );
                        for ( int p = 0; p < transition[s].Length; p++ )
                        {
                            Console.Error.Write( transition[s][p] + " " );
                        }
                        Console.Error.WriteLine();
                    }
                    NoViableAlt( s, input );
                    return 0;
                }
            }
            finally
            {
                input.Rewind( mark );
            }
        }

        protected virtual void NoViableAlt( int s, IIntStream input )
        {
            if ( recognizer.state.backtracking > 0 )
            {
                recognizer.state.failed = true;
                return;
            }
            NoViableAltException nvae =
                new NoViableAltException( Description,
                                         decisionNumber,
                                         s,
                                         input );
            Error( nvae );
            throw nvae;
        }

        /** <summary>A hook for debugging interface</summary> */
        public virtual void Error( NoViableAltException nvae )
        {
        }

        public SpecialStateTransitionHandler SpecialStateTransition
        {
            get;
            private set;
        }
        //public virtual int specialStateTransition( int s, IntStream input )
        //{
        //    return -1;
        //}

        static int SpecialStateTransitionDefault( DFA dfa, int s, IIntStream input )
        {
            return -1;
        }

        /** <summary>
         *  Given a String that has a run-length-encoding of some unsigned shorts
         *  like "\1\2\3\9", convert to short[] {2,9,9,9}.  We do this to avoid
         *  static short[] which generates so much init code that the class won't
         *  compile. :(
         *  </summary>
         */
        public static short[] UnpackEncodedString( string encodedString )
        {
            // walk first to find how big it is.
            int size = 0;
            for ( int i = 0; i < encodedString.Length; i += 2 )
            {
                size += encodedString[i];
            }
            short[] data = new short[size];
            int di = 0;
            for ( int i = 0; i < encodedString.Length; i += 2 )
            {
                char n = encodedString[i];
                char v = encodedString[i + 1];
                // add v n times to data
                for ( int j = 1; j <= n; j++ )
                {
                    data[di++] = (short)v;
                }
            }
            return data;
        }

        /** <summary>Hideous duplication of code, but I need different typed arrays out :(</summary> */
        public static char[] UnpackEncodedStringToUnsignedChars( string encodedString )
        {
            // walk first to find how big it is.
            int size = 0;
            for ( int i = 0; i < encodedString.Length; i += 2 )
            {
                size += encodedString[i];
            }
            char[] data = new char[size];
            int di = 0;
            for ( int i = 0; i < encodedString.Length; i += 2 )
            {
                char n = encodedString[i];
                char v = encodedString[i + 1];
                // add v n times to data
                for ( int j = 1; j <= n; j++ )
                {
                    data[di++] = v;
                }
            }
            return data;
        }

        [Conditional("ANTLR_DEBUG")]
        protected virtual void DebugRecognitionException(RecognitionException ex)
        {
            IDebugEventListener dbg = recognizer.DebugListener;
            if (dbg != null)
                dbg.RecognitionException(ex);
        }
    }
}
