using System;
using System.Diagnostics;

namespace Lucene.Net.Util
{
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    public static class RollingBuffer
    {
        public interface Resettable
        {
            void Reset();
        }
    }

    /// <summary>
    /// Acts like forever growing T[], but internally uses a
    ///  circular buffer to reuse instances of T.
    ///
    ///  @lucene.internal
    /// </summary>
    public abstract class RollingBuffer<T>
        where T : RollingBuffer.Resettable
    {
        private T[] Buffer = new T[8];

        // Next array index to write to:
        private int NextWrite;

        // Next position to write:
        private int NextPos;

        // How many valid Position are held in the
        // array:
        private int Count;

        protected RollingBuffer()
        {
            for (var idx = 0; idx < Buffer.Length; idx++)
            {
                Buffer[idx] = NewInstance(); // TODO GIVE ROLLING BUFFER A DELEGATE FOR NEW INSTANCE
            }
        }

        protected RollingBuffer(Func<T> factory)
        {
            for (int idx = 0; idx < Buffer.Length; idx++)
            {
                Buffer[idx] = factory();
            }
        }

        protected internal abstract T NewInstance();

        public virtual void Reset()
        {
            NextWrite--;
            while (Count > 0)
            {
                if (NextWrite == -1)
                {
                    NextWrite = Buffer.Length - 1;
                }
                Buffer[NextWrite--].Reset();
                Count--;
            }
            NextWrite = 0;
            NextPos = 0;
            Count = 0;
        }

        // For assert:
        private bool InBounds(int pos)
        {
            return pos < NextPos && pos >= NextPos - Count;
        }

        private int GetIndex(int pos)
        {
            int index = NextWrite - (NextPos - pos);
            if (index < 0)
            {
                index += Buffer.Length;
            }
            return index;
        }

        /// <summary>
        /// Get T instance for this absolute position;
        ///  this is allowed to be arbitrarily far "in the
        ///  future" but cannot be before the last freeBefore.
        /// </summary>
        public virtual T Get(int pos)
        {
            //System.out.println("RA.get pos=" + pos + " nextPos=" + nextPos + " nextWrite=" + nextWrite + " count=" + count);
            while (pos >= NextPos)
            {
                if (Count == Buffer.Length)
                {
                    var newBuffer = new T[ArrayUtil.Oversize(1 + Count, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
                    Array.Copy(Buffer, NextWrite, newBuffer, 0, Buffer.Length - NextWrite);
                    Array.Copy(Buffer, 0, newBuffer, Buffer.Length - NextWrite, NextWrite);
                    for (int i = Buffer.Length; i < newBuffer.Length; i++)
                    {
                        newBuffer[i] = NewInstance();
                    }
                    NextWrite = Buffer.Length;
                    Buffer = newBuffer;
                }
                if (NextWrite == Buffer.Length)
                {
                    NextWrite = 0;
                }
                // Should have already been reset:
                NextWrite++;
                NextPos++;
                Count++;
            }
            Debug.Assert(InBounds(pos));
            int index = GetIndex(pos);
            return Buffer[index];
        }

        /// <summary>
        /// Returns the maximum position looked up, or -1 if no
        ///  position has been looked up sinc reset/init.
        /// </summary>
        public virtual int MaxPos
        {
            get
            {
                return NextPos - 1;
            }
        }

        public virtual void FreeBefore(int pos)
        {
            int toFree = Count - (NextPos - pos);
            Debug.Assert(toFree >= 0);
            Debug.Assert(toFree <= Count, "toFree=" + toFree + " count=" + Count);
            int index = NextWrite - Count;
            if (index < 0)
            {
                index += Buffer.Length;
            }
            for (int i = 0; i < toFree; i++)
            {
                if (index == Buffer.Length)
                {
                    index = 0;
                }
                //System.out.println("  fb idx=" + index);
                Buffer[index].Reset();
                index++;
            }
            Count -= toFree;
        }
    }
}