﻿/*
 * NOTE TO JL: The original contains references to 3.5-only stuff!
 * 
 * [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 System.Collections.Generic;

    using ArgumentOutOfRangeException = System.ArgumentOutOfRangeException;
    using InvalidOperationException = System.InvalidOperationException;
    using StringBuilder = System.Text.StringBuilder;

    /** <summary>
     *  The most common stream of tokens is one where every token is buffered up
     *  and tokens are prefiltered for a certain channel (the parser will only
     *  see these tokens and cannot change the filter channel number during the
     *  parse).
     *  </summary>
     *
     *  <remarks>TODO: how to access the full token stream?  How to track all tokens matched per rule?</remarks>
     */
    [System.Serializable]
    public class LegacyCommonTokenStream : ITokenStream {
        [System.NonSerialized]
        ITokenSource _tokenSource;

        /** <summary>
         *  Record every single token pulled from the source so we can reproduce
         *  chunks of it later.
         *  </summary>
         */
        protected List<IToken> tokens;

        /** <summary>Map<tokentype, channel> to override some Tokens' channel numbers</summary> */
        protected IDictionary<int, int> channelOverrideMap;

        /** <summary>Set<tokentype>; discard any tokens with this type</summary> */
        protected Dictionary<int, int> discardSet;

        /** <summary>Skip tokens on any channel but this one; this is how we skip whitespace...</summary> */
        protected int channel = TokenChannels.Default;

        /** <summary>By default, track all incoming tokens</summary> */
        protected bool discardOffChannelTokens = false;

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

        /** <summary>
         *  The index into the tokens list of the current token (next token
         *  to consume).  p==-1 indicates that the tokens list is empty
         *  </summary>
         */
        protected int p = -1;

        public LegacyCommonTokenStream() {
            tokens = new List<IToken>(500);
        }

        public LegacyCommonTokenStream(ITokenSource tokenSource)
            : this() {
            this._tokenSource = tokenSource;
        }

        public LegacyCommonTokenStream(ITokenSource tokenSource, int channel)
            : this(tokenSource) {
            this.channel = channel;
        }

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

        /// <summary>
        /// How deep have we gone?
        /// </summary>
        public virtual int Range {
            get;
            protected set;
        }

        /** <summary>Reset this token stream by setting its token source.</summary> */
        public virtual void SetTokenSource(ITokenSource tokenSource) {
            this._tokenSource = tokenSource;
            tokens.Clear();
            p = -1;
            channel = TokenChannels.Default;
        }

        /** <summary>
         *  Load all tokens from the token source and put in tokens.
         *  This is done upon first LT request because you might want to
         *  set some token type / channel overrides before filling buffer.
         *  </summary>
         */
        public virtual void FillBuffer() {
            // fast return if the buffer is already full
            if (p != -1)
                return;

            int index = 0;
            IToken t = _tokenSource.NextToken();
            while (t != null && t.Type != CharStreamConstants.EndOfFile) {
                bool discard = false;
                // is there a channel override for token type?
                int channelI;
                if (channelOverrideMap != null && channelOverrideMap.TryGetValue(t.Type, out channelI))
                    t.Channel = channelI;

                //if ( channelOverrideMap != null && channelOverrideMap.ContainsKey( t.getType() ) )
                //{
                //    object channelI = channelOverrideMap.get( t.getType() );
                //    if ( channelI != null )
                //    {
                //        t.setChannel( (int)channelI );
                //    }
                //}
                if (discardSet != null &&
                     discardSet.ContainsKey(t.Type)) {
                    discard = true;
                } else if (discardOffChannelTokens && t.Channel != this.channel) {
                    discard = true;
                }
                if (!discard) {
                    t.TokenIndex = index;
                    tokens.Add(t);
                    index++;
                }
                t = _tokenSource.NextToken();
            }
            // leave p pointing at first token on channel
            p = 0;
            p = SkipOffTokenChannels(p);
        }

        /** <summary>
         *  Move the input pointer to the next incoming token.  The stream
         *  must become active with LT(1) available.  consume() simply
         *  moves the input pointer so that LT(1) points at the next
         *  input symbol. Consume at least one token.
         *  </summary>
         *
         *  <remarks>
         *  Walk past any token not on the channel the parser is listening to.
         *  </remarks>
         */
        public virtual void Consume() {
            if (p < tokens.Count) {
                p++;
                p = SkipOffTokenChannels(p); // leave p on valid token
            }
        }

        /** <summary>Given a starting index, return the index of the first on-channel token.</summary> */
        protected virtual int SkipOffTokenChannels(int i) {
            int n = tokens.Count;
            while (i < n && ((IToken)tokens[i]).Channel != channel) {
                i++;
            }
            return i;
        }

        protected virtual int SkipOffTokenChannelsReverse(int i) {
            while (i >= 0 && ((IToken)tokens[i]).Channel != channel) {
                i--;
            }
            return i;
        }

        /** <summary>
         *  A simple filter mechanism whereby you can tell this token stream
         *  to force all tokens of type ttype to be on channel.  For example,
         *  when interpreting, we cannot exec actions so we need to tell
         *  the stream to force all WS and NEWLINE to be a different, ignored
         *  channel.
         *  </summary>
         */
        public virtual void SetTokenTypeChannel(int ttype, int channel) {
            if (channelOverrideMap == null) {
                channelOverrideMap = new Dictionary<int, int>();
            }
            channelOverrideMap[ttype] = channel;
        }

        public virtual void DiscardTokenType(int ttype) {
            if (discardSet == null) {
                discardSet = new Dictionary<int, int>();
            }
            discardSet.Add(ttype, ttype);
        }

        public virtual void SetDiscardOffChannelTokens(bool discardOffChannelTokens) {
            this.discardOffChannelTokens = discardOffChannelTokens;
        }

        public virtual IList<IToken> GetTokens() {
            if (p == -1) {
                FillBuffer();
            }
            return tokens;
        }

        public virtual IList<IToken> GetTokens(int start, int stop) {
            return GetTokens(start, stop, (BitSet)null);
        }

        /** <summary>
         *  Given a start and stop index, return a List of all tokens in
         *  the token type BitSet.  Return null if no tokens were found.  This
         *  method looks at both on and off channel tokens.
         *  </summary>
         */
        public virtual IList<IToken> GetTokens(int start, int stop, BitSet types) {
            if (p == -1) {
                FillBuffer();
            }
            if (stop >= tokens.Count) {
                stop = tokens.Count - 1;
            }
            if (start < 0) {
                start = 0;
            }
            if (start > stop) {
                return null;
            }

            // list = tokens[start:stop]:{Token t, t.getType() in types}
            IList<IToken> filteredTokens = new List<IToken>();
            for (int i = start; i <= stop; i++) {
                IToken t = tokens[i];
                if (types == null || types.Member(t.Type)) {
                    filteredTokens.Add(t);
                }
            }
            if (filteredTokens.Count == 0) {
                filteredTokens = null;
            }
            return filteredTokens;
        }

        public virtual IList<IToken> GetTokens(int start, int stop, IList<int> types) {
            return GetTokens(start, stop, new BitSet(types));
        }

        public virtual IList<IToken> GetTokens(int start, int stop, int ttype) {
            return GetTokens(start, stop, BitSet.Of(ttype));
        }

        /** <summary>
         *  Get the ith token from the current position 1..n where k=1 is the
         *  first symbol of lookahead.
         *  </summary>
         */
        public virtual IToken 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) >= tokens.Count) {
                return tokens[tokens.Count - 1];
            }
            //System.out.println(tokens.get(p+k-1));
            int i = p;
            int n = 1;
            // find k good tokens
            while (n < k) {
                // skip off-channel tokens
                i = SkipOffTokenChannels(i + 1); // leave p on valid token
                n++;
            }
            if (i >= tokens.Count) {
                return tokens[tokens.Count - 1];
            }

            if (i > Range)
                Range = i;

            return (IToken)tokens[i];
        }

        /** <summary>Look backwards k tokens on-channel tokens</summary> */
        protected virtual IToken LB(int k) {
            //System.out.print("LB(p="+p+","+k+") ");
            if (p == -1) {
                FillBuffer();
            }
            if (k == 0) {
                return null;
            }
            if ((p - k) < 0) {
                return null;
            }

            int i = p;
            int n = 1;
            // find k good tokens looking backwards
            while (n <= k) {
                // skip off-channel tokens
                i = SkipOffTokenChannelsReverse(i - 1); // leave p on valid token
                n++;
            }
            if (i < 0) {
                return null;
            }
            return (IToken)tokens[i];
        }

        /** <summary>
         *  Return absolute token i; ignore which channel the tokens are on;
         *  that is, count all tokens not just on-channel tokens.
         *  </summary>
         */
        public virtual IToken Get(int i) {
            return (IToken)tokens[i];
        }

#if false
        /** Get all tokens from start..stop inclusively */
        public virtual List<IToken> Get(int start, int count)
        {
            if (start < 0)
                throw new ArgumentOutOfRangeException("start");
            if (count < 0)
                throw new ArgumentOutOfRangeException("count");

            if (p == -1)
                FillBuffer();

            return new List<IToken>(tokens.Skip(start).Take(count));
        }
#endif

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

        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 Count {
            get {
                return tokens.Count;
            }
        }

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

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

        public virtual void Reset() {
            p = 0;
            lastMarker = 0;
        }

        public virtual void Seek(int index) {
            p = index;
        }

        public virtual ITokenSource TokenSource {
            get {
                return _tokenSource;
            }
        }

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

        public override string ToString() {
            if (p == -1) {
                throw new InvalidOperationException("Buffer is not yet filled.");
            }
            return ToString(0, tokens.Count - 1);
        }

        public virtual string ToString(int start, int stop) {
            if (start < 0 || stop < 0) {
                return null;
            }
            if (p == -1) {
                throw new InvalidOperationException("Buffer is not yet filled.");
            }
            if (stop >= tokens.Count) {
                stop = tokens.Count - 1;
            }
            StringBuilder buf = new StringBuilder();
            for (int i = start; i <= stop; i++) {
                IToken t = tokens[i];
                buf.Append(t.Text);
            }
            return buf.ToString();
        }

        public virtual string ToString(IToken start, IToken stop) {
            if (start != null && stop != null) {
                return ToString(start.TokenIndex, stop.TokenIndex);
            }
            return null;
        }
    }
}
