﻿/*
 * [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 CLSCompliant = System.CLSCompliantAttribute;
    using IndexOutOfRangeException = System.IndexOutOfRangeException;
    using StringBuilder = System.Text.StringBuilder;

    /** Buffer all input tokens but do on-demand fetching of new tokens from
     *  lexer. Useful when the parser or lexer has to set context/mode info before
     *  proper lexing of future tokens. The ST template parser needs this,
     *  for example, because it has to constantly flip back and forth between
     *  inside/output templates. E.g., <names:{hi, <it>}> has to parse names
     *  as part of an expression but "hi, <it>" as a nested template.
     *
     *  You can't use this stream if you pass whitespace or other off-channel
     *  tokens to the parser. The stream can't ignore off-channel tokens.
     *  (UnbufferedTokenStream is the same way.)
     *
     *  This is not a subclass of UnbufferedTokenStream because I don't want
     *  to confuse small moving window of tokens it uses for the full buffer.
     */
    [System.Serializable]
    public class BufferedTokenStream : ITokenStream, ITokenStreamInformation {
        private ITokenSource _tokenSource;

        /** Record every single token pulled from the source so we can reproduce
         *  chunks of it later.  The buffer in LookaheadStream overlaps sometimes
         *  as its moving window moves through the input.  This list captures
         *  everything so we can access complete input text.
         */
        [CLSCompliant(false)]
        protected List<IToken> _tokens = new List<IToken>(100);

        /** Track the last mark() call result value for use in rewind(). */
        private int _lastMarker;

        /** The index into the tokens list of the current token (next token
         *  to consume).  tokens[p] should be LT(1).  p=-1 indicates need
         *  to initialize with first token.  The ctor doesn't get a token.
         *  First call to LT(1) or whatever gets the first token and sets p=0;
         */
        [CLSCompliant(false)]
        protected int _p = -1;

        public BufferedTokenStream() {
        }

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

        public virtual ITokenSource TokenSource {
            get {
                return _tokenSource;
            }
            set {
                this._tokenSource = value;
                _tokens.Clear();
                _p = -1;
            }
        }

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

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

        public virtual int Count {
            get {
                return _tokens.Count;
            }
        }

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

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

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

                return token;
            }
        }

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

        public virtual int Mark() {
            if (_p == -1)
                Setup();
            _lastMarker = Index;
            return _lastMarker;
        }

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

        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;
        }

        /** 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.
         *
         *  Walk past any token not on the channel the parser is listening to.
         */
        public virtual void Consume() {
            if (_p == -1)
                Setup();
            _p++;
            Sync(_p);
        }

        /** Make sure index i in tokens has a token. */
        protected virtual void Sync(int i) {
            int n = i - _tokens.Count + 1; // how many more elements we need?
            if (n > 0)
                Fetch(n);
        }

        /** add n elements to buffer */
        protected virtual void Fetch(int n) {
            for (int i = 0; i < n; i++) {
                IToken t = TokenSource.NextToken();
                t.TokenIndex = _tokens.Count;
                _tokens.Add(t);
                if (t.Type == CharStreamConstants.EndOfFile)
                    break;
            }
        }

        public virtual IToken Get(int i) {
            if (i < 0 || i >= _tokens.Count) {
                throw new IndexOutOfRangeException("token index " + i + " out of range 0.." + (_tokens.Count - 1));
            }
            return _tokens[i];
        }

#if false // why is this different from GetTokens(start, count) ?
        /// <summary>
        /// Get all tokens from start..(start+count-1) inclusively
        /// </summary>
        public virtual List<IToken> Get(int start, int count)
        {
            if (start < 0)
                throw new ArgumentOutOfRangeException("start");
            if (count < 0)
                throw new ArgumentOutOfRangeException("count");
            if (start + count >= _tokens.Count)
                throw new ArgumentException();

            if (_p == -1)
                Setup();

            List<IToken> subset = new List<IToken>(count);
            for (int i = 0; i < count; i++)
            {
                IToken token = _tokens[i];
                if (token.Type == TokenTypes.EndOfFile)
                    break;

                subset.Add(token);
            }

            return subset;
        }
#endif

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

        protected virtual IToken LB(int k) {
            if ((_p - k) < 0)
                return null;

            return _tokens[_p - k];
        }

        public virtual IToken LT(int k) {
            if (_p == -1)
                Setup();
            if (k == 0)
                return null;
            if (k < 0)
                return LB(-k);

            int i = _p + k - 1;
            Sync(i);
            if (i >= _tokens.Count) {
                // EOF must be last token
                return _tokens[_tokens.Count - 1];
            }

            if (i > Range)
                Range = i;

            return _tokens[_p + k - 1];
        }

        protected virtual void Setup() {
            Sync(0);
            _p = 0;
        }

        public virtual List<IToken> GetTokens() {
            return _tokens;
        }

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

        /** 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.
         */
        public virtual List<IToken> GetTokens(int start, int stop, BitSet types) {
            if (_p == -1)
                Setup();
            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}
            List<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 List<IToken> GetTokens(int start, int stop, IEnumerable<int> types) {
            return GetTokens(start, stop, new BitSet(types));
        }

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

        public override string ToString() {
            if (_p == -1)
                Setup();

            Fill();
            return ToString(0, _tokens.Count - 1);
        }

        public virtual string ToString(int start, int stop) {
            if (start < 0 || stop < 0)
                return null;
            if (_p == -1)
                Setup();
            if (stop >= _tokens.Count)
                stop = _tokens.Count - 1;

            StringBuilder buf = new StringBuilder();
            for (int i = start; i <= stop; i++) {
                IToken t = _tokens[i];
                if (t.Type == CharStreamConstants.EndOfFile)
                    break;
                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;
        }

        public virtual void Fill() {
            if (_p == -1)
                Setup();

            if (_tokens[_p].Type == CharStreamConstants.EndOfFile)
                return;

            int i = _p + 1;
            Sync(i);
            while (_tokens[i].Type != CharStreamConstants.EndOfFile) {
                i++;
                Sync(i);
            }
        }
    }
}
