/*
 * [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 Antlr.Runtime.Tree;

    using ArgumentException = System.ArgumentException;
    using ArgumentNullException = System.ArgumentNullException;
    using Exception = System.Exception;
    using SerializationInfo = System.Runtime.Serialization.SerializationInfo;
    using StreamingContext = System.Runtime.Serialization.StreamingContext;

    /** <summary>The root of the ANTLR exception hierarchy.</summary>
     *
     *  <remarks>
     *  To avoid English-only error messages and to generally make things
     *  as flexible as possible, these exceptions are not created with strings,
     *  but rather the information necessary to generate an error.  Then
     *  the various reporting methods in Parser and Lexer can be overridden
     *  to generate a localized error message.  For example, MismatchedToken
     *  exceptions are built with the expected token type.
     *  So, don't expect getMessage() to return anything.
     *
     *  Note that as of Java 1.4, you can access the stack trace, which means
     *  that you can compute the complete trace of rules from the start symbol.
     *  This gives you considerable context information with which to generate
     *  useful error messages.
     *
     *  ANTLR generates code that throws exceptions upon recognition error and
     *  also generates code to catch these exceptions in each rule.  If you
     *  want to quit upon first error, you can turn off the automatic error
     *  handling mechanism using rulecatch action, but you still need to
     *  override methods mismatch and recoverFromMismatchSet.
     *
     *  In general, the recognition exceptions can track where in a grammar a
     *  problem occurred and/or what was the expected input.  While the parser
     *  knows its state (such as current input symbol and line info) that
     *  state can change before the exception is reported so current token index
     *  is computed and stored at exception time.  From this info, you can
     *  perhaps print an entire line of input not just a single token, for example.
     *  Better to just say the recognizer had a problem and then let the parser
     *  figure out a fancy report.
     *  </remarks>
     */
    [System.Serializable]
    public class RecognitionException : Exception
    {
        /** <summary>What input stream did the error occur in?</summary> */
        private IIntStream _input;

        /** <summary>What is index of token/char were we looking at when the error occurred?</summary> */
        private int _index;

        /** <summary>
         *  The current Token when an error occurred.  Since not all streams
         *  can retrieve the ith Token, we have to track the Token object.
         *  For parsers.  Even when it's a tree parser, token might be set.
         *  </summary>
         */
        private IToken _token;

        /** <summary>
         *  If this is a tree parser exception, node is set to the node with
         *  the problem.
         *  </summary>
         */
        private object _node;

        /** <summary>The current char when an error occurred. For lexers.</summary> */
        private int _c;

        /** <summary>
         *  Track the line (1-based) at which the error occurred in case this is
         *  generated from a lexer.  We need to track this since the
         *  unexpected char doesn't carry the line info.
         *  </summary>
         */
        private int _line;

        /// <summary>
        /// The 0-based index into the line where the error occurred.
        /// </summary>
        private int _charPositionInLine;

        /** <summary>
         *  If you are parsing a tree node stream, you will encounter som
         *  imaginary nodes w/o line/col info.  We now search backwards looking
         *  for most recent token with line/col info, but notify getErrorHeader()
         *  that info is approximate.
         *  </summary>
         */
        private bool _approximateLineInfo;

        /** <summary>Used for remote debugger deserialization</summary> */
        public RecognitionException()
            : this("A recognition error occurred.", null, null)
        {
        }

        public RecognitionException( IIntStream input )
            : this("A recognition error occurred.", input, null)
        {
        }

        public RecognitionException(string message)
            : this(message, null, null)
        {
        }

        public RecognitionException(string message, IIntStream input)
            : this(message, input, null)
        {
        }

        public RecognitionException(string message, Exception innerException)
            : this(message, null, innerException)
        {
        }

        public RecognitionException(string message, IIntStream input, Exception innerException)
            : base(message, innerException)
        {
            this._input = input;
            if (input != null)
            {
                this._index = input.Index;
                if (input is ITokenStream)
                {
                    this._token = ((ITokenStream)input).LT(1);
                    this._line = _token.Line;
                    this._charPositionInLine = _token.CharPositionInLine;
                }

                ITreeNodeStream tns = input as ITreeNodeStream;
                if (tns != null)
                {
                    ExtractInformationFromTreeNodeStream(tns);
                }
                else
                {
                    ICharStream charStream = input as ICharStream;
                    if (charStream != null)
                    {
                        this._c = input.LA(1);
                        this._line = ((ICharStream)input).Line;
                        this._charPositionInLine = ((ICharStream)input).CharPositionInLine;
                    }
                    else
                    {
                        this._c = input.LA(1);
                    }
                }
            }
        }

        protected RecognitionException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            if (info == null)
                throw new ArgumentNullException("info");

            _index = info.GetInt32("Index");
            _c = info.GetInt32("C");
            _line = info.GetInt32("Line");
            _charPositionInLine = info.GetInt32("CharPositionInLine");
            _approximateLineInfo = info.GetBoolean("ApproximateLineInfo");
        }

        /** <summary>Return the token type or char of the unexpected input element</summary> */
        public virtual int UnexpectedType
        {
            get
            {
                if ( _input is ITokenStream )
                {
                    return _token.Type;
                }

                ITreeNodeStream treeNodeStream = _input as ITreeNodeStream;
                if ( treeNodeStream != null )
                {
                    ITreeAdaptor adaptor = treeNodeStream.TreeAdaptor;
                    return adaptor.GetType( _node );
                }

                return _c;
            }
        }

        public bool ApproximateLineInfo
        {
            get
            {
                return _approximateLineInfo;
            }
            protected set
            {
                _approximateLineInfo = value;
            }
        }

        public IIntStream Input
        {
            get
            {
                return _input;
            }
            protected set
            {
                _input = value;
            }
        }

        public IToken Token
        {
            get
            {
                return _token;
            }
            set
            {
                _token = value;
            }
        }

        public object Node
        {
            get
            {
                return _node;
            }
            protected set
            {
                _node = value;
            }
        }

        public int Character
        {
            get
            {
                return _c;
            }
            protected set
            {
                _c = value;
            }
        }

        public int Index
        {
            get
            {
                return _index;
            }
            protected set
            {
                _index = value;
            }
        }

        public int Line
        {
            get
            {
                return _line;
            }
            set
            {
                _line = value;
            }
        }

        public int CharPositionInLine
        {
            get
            {
                return _charPositionInLine;
            }
            set
            {
                _charPositionInLine = value;
            }
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new ArgumentNullException("info");

            base.GetObjectData(info, context);
            info.AddValue("Index", _index);
            info.AddValue("C", _c);
            info.AddValue("Line", _line);
            info.AddValue("CharPositionInLine", _charPositionInLine);
            info.AddValue("ApproximateLineInfo", _approximateLineInfo);
        }

        protected virtual void ExtractInformationFromTreeNodeStream(ITreeNodeStream input)
        {
            this._node = input.LT(1);
            ITokenStreamInformation streamInformation = input as ITokenStreamInformation;
            if (streamInformation != null)
            {
                IToken lastToken = streamInformation.LastToken;
                IToken lastRealToken = streamInformation.LastRealToken;
                if (lastRealToken != null)
                {
                    this._token = lastRealToken;
                    this._line = lastRealToken.Line;
                    this._charPositionInLine = lastRealToken.CharPositionInLine;
                    this._approximateLineInfo = lastRealToken.Equals(lastToken);
                }
            }
            else
            {
                ITreeAdaptor adaptor = input.TreeAdaptor;
                IToken payload = adaptor.GetToken(_node);
                if (payload != null)
                {
                    this._token = payload;
                    if (payload.Line <= 0)
                    {
                        // imaginary node; no line/pos info; scan backwards
                        int i = -1;
                        object priorNode = input.LT(i);
                        while (priorNode != null)
                        {
                            IToken priorPayload = adaptor.GetToken(priorNode);
                            if (priorPayload != null && priorPayload.Line > 0)
                            {
                                // we found the most recent real line / pos info
                                this._line = priorPayload.Line;
                                this._charPositionInLine = priorPayload.CharPositionInLine;
                                this._approximateLineInfo = true;
                                break;
                            }
                            --i;
                            try
                            {
                                priorNode = input.LT(i);
                            }
                            catch (ArgumentException)
                            {
                                priorNode = null;
                            }
                        }
                    }
                    else
                    {
                        // node created from real token
                        this._line = payload.Line;
                        this._charPositionInLine = payload.CharPositionInLine;
                    }
                }
                else if (this._node is Tree.ITree)
                {
                    this._line = ((Tree.ITree)this._node).Line;
                    this._charPositionInLine = ((Tree.ITree)this._node).CharPositionInLine;
                    if (this._node is CommonTree)
                    {
                        this._token = ((CommonTree)this._node).Token;
                    }
                }
                else
                {
                    int type = adaptor.GetType(this._node);
                    string text = adaptor.GetText(this._node);
                    this._token = new CommonToken(type, text);
                }
            }
        }
    }
}
