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

    /** <summary>
     *  A generic list of elements tracked in an alternative to be used in
     *  a -> rewrite rule.  We need to subclass to fill in the next() method,
     *  which returns either an AST node wrapped around a token payload or
     *  an existing subtree.
     *  </summary>
     *
     *  <remarks>
     *  Once you start next()ing, do not try to add more elements.  It will
     *  break the cursor tracking I believe.
     *
     *  TODO: add mechanism to detect/puke on modification after reading from stream
     *  </remarks>
     *
     *  <see cref="RewriteRuleSubtreeStream"/>
     *  <see cref="RewriteRuleTokenStream"/>
     */
    [System.Serializable]
    public abstract class RewriteRuleElementStream
    {
        /** <summary>
         *  Cursor 0..n-1.  If singleElement!=null, cursor is 0 until you next(),
         *  which bumps it to 1 meaning no more elements.
         *  </summary>
         */
        protected int cursor = 0;

        /** <summary>Track single elements w/o creating a list.  Upon 2nd add, alloc list */
        protected object singleElement;

        /** <summary>The list of tokens or subtrees we are tracking */
        protected IList elements;

        /** <summary>Once a node / subtree has been used in a stream, it must be dup'd
         *  from then on.  Streams are reset after subrules so that the streams
         *  can be reused in future subrules.  So, reset must set a dirty bit.
         *  If dirty, then next() always returns a dup.
         *
         *  I wanted to use "naughty bit" here, but couldn't think of a way
         *  to use "naughty".
         */
        protected bool dirty = false;

        /** <summary>The element or stream description; usually has name of the token or
         *  rule reference that this list tracks.  Can include rulename too, but
         *  the exception would track that info.
         */
        protected string elementDescription;
        protected ITreeAdaptor adaptor;

        public RewriteRuleElementStream( ITreeAdaptor adaptor, string elementDescription )
        {
            this.elementDescription = elementDescription;
            this.adaptor = adaptor;
        }

        /** <summary>Create a stream with one element</summary> */
        public RewriteRuleElementStream( ITreeAdaptor adaptor, string elementDescription, object oneElement )
            : this( adaptor, elementDescription )
        {
            Add( oneElement );
        }

        /** <summary>Create a stream, but feed off an existing list</summary> */
        public RewriteRuleElementStream( ITreeAdaptor adaptor, string elementDescription, IList elements )
            : this( adaptor, elementDescription )
        {
            this.singleElement = null;
            this.elements = elements;
        }

        /** <summary>
         *  Reset the condition of this stream so that it appears we have
         *  not consumed any of its elements.  Elements themselves are untouched.
         *  Once we reset the stream, any future use will need duplicates.  Set
         *  the dirty bit.
         *  </summary>
         */
        public virtual void Reset()
        {
            cursor = 0;
            dirty = true;
        }

        public virtual void Add( object el )
        {
            //System.out.println("add '"+elementDescription+"' is "+el);
            if ( el == null )
            {
                return;
            }
            if ( elements != null )
            { // if in list, just add
                elements.Add( el );
                return;
            }
            if ( singleElement == null )
            { // no elements yet, track w/o list
                singleElement = el;
                return;
            }
            // adding 2nd element, move to list
            elements = new List<object>( 5 );
            elements.Add( singleElement );
            singleElement = null;
            elements.Add( el );
        }

        /** <summary>
         *  Return the next element in the stream.  If out of elements, throw
         *  an exception unless size()==1.  If size is 1, then return elements[0].
         *  Return a duplicate node/subtree if stream is out of elements and
         *  size==1.  If we've already used the element, dup (dirty bit set).
         *  </summary>
         */
        public virtual object NextTree()
        {
            int n = Count;
            if ( dirty || ( cursor >= n && n == 1 ) )
            {
                // if out of elements and size is 1, dup
                object el = NextCore();
                return Dup( el );
            }
            // test size above then fetch
            object el2 = NextCore();
            return el2;
        }

        /** <summary>
         *  Do the work of getting the next element, making sure that it's
         *  a tree node or subtree.  Deal with the optimization of single-
         *  element list versus list of size > 1.  Throw an exception
         *  if the stream is empty or we're out of elements and size>1.
         *  protected so you can override in a subclass if necessary.
         *  </summary>
         */
        protected virtual object NextCore()
        {
            int n = Count;
            if ( n == 0 )
            {
                throw new RewriteEmptyStreamException( elementDescription );
            }
            if ( cursor >= n )
            { // out of elements?
                if ( n == 1 )
                {  // if size is 1, it's ok; return and we'll dup
                    return ToTree( singleElement );
                }
                // out of elements and size was not 1, so we can't dup
                throw new RewriteCardinalityException( elementDescription );
            }
            // we have elements
            if ( singleElement != null )
            {
                cursor++; // move cursor even for single element list
                return ToTree( singleElement );
            }
            // must have more than one in list, pull from elements
            object o = ToTree( elements[cursor] );
            cursor++;
            return o;
        }

        /** <summary>
         *  When constructing trees, sometimes we need to dup a token or AST
         * 	subtree.  Dup'ing a token means just creating another AST node
         *  around it.  For trees, you must call the adaptor.dupTree() unless
         *  the element is for a tree root; then it must be a node dup.
         *  </summary>
         */
        protected abstract object Dup( object el );

        /** <summary>
         *  Ensure stream emits trees; tokens must be converted to AST nodes.
         *  AST nodes can be passed through unmolested.
         *  </summary>
         */
        protected virtual object ToTree( object el )
        {
            return el;
        }

        public virtual bool HasNext
        {
            get
            {
                return ( singleElement != null && cursor < 1 ) ||
                      ( elements != null && cursor < elements.Count );
            }
        }

        public virtual int Count
        {
            get
            {
                int n = 0;
                if ( singleElement != null )
                {
                    n = 1;
                }
                if ( elements != null )
                {
                    return elements.Count;
                }
                return n;
            }
        }

        public virtual string Description
        {
            get
            {
                return elementDescription;
            }
        }
    }
}
