﻿using Lucene.Net.Codecs.Sep;
using Lucene.Net.Diagnostics;
using Lucene.Net.Store;
using System.Diagnostics;

namespace Lucene.Net.Codecs.IntBlock
{
    /*
     * 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.
     */



    /// <summary>
    /// Abstract base class that reads fixed-size blocks of ints
    /// from an <see cref="IndexInput"/>.  While this is a simple approach, a
    /// more performant approach would directly create an impl
    /// of <see cref="Int32IndexInput"/> inside <see cref="Directory"/>.  Wrapping a generic
    /// <see cref="IndexInput"/> will likely cost performance.
    /// <para/>
    /// NOTE: This was FixedIntBlockIndexInput in Lucene
    /// <para/>
    /// @lucene.experimental
    /// </summary>
    /// <remarks>
    /// Naive int block API that writes vInts.  This is
    /// expected to give poor performance; it's really only for
    /// testing the pluggability.  One should typically use pfor instead.
    /// </remarks>
    public abstract class FixedInt32BlockIndexInput : Int32IndexInput
    {
        private readonly IndexInput input;
        protected readonly int m_blockSize;

        public FixedInt32BlockIndexInput(IndexInput @in)
        {
            input = @in;
            m_blockSize = @in.ReadVInt32();
        }

        public override Int32IndexInput.Reader GetReader()
        {
            var buffer = new int[m_blockSize];
            var clone = (IndexInput)input.Clone();
            // TODO: can this be simplified?
            return new Reader(clone, buffer, GetBlockReader(clone, buffer));
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                input.Dispose();
            }
        }

        public override Int32IndexInput.Index GetIndex()
        {
            return new Index(this);
        }

        protected abstract IBlockReader GetBlockReader(IndexInput @in, int[] buffer);


        /// <summary>
        /// Interface for fixed-size block decoders.
        /// <para>
        /// Implementations should decode into the buffer in <see cref="ReadBlock()"/>.
        /// </para>
        /// </summary>
        public interface IBlockReader
        {
            void ReadBlock();
        }

        new private class Reader : Int32IndexInput.Reader
        {
            private readonly IndexInput input;
            private readonly IBlockReader blockReader;
            private readonly int blockSize;
            private readonly int[] pending;

            private int upto;
            private bool seekPending;
            private long pendingFP;
            private long lastBlockFP = -1;

            public Reader(IndexInput input, int[] pending, IBlockReader blockReader)
            {
                this.input = input;
                this.pending = pending;
                this.blockSize = pending.Length;
                this.blockReader = blockReader;
                upto = blockSize;
            }

            internal virtual void Seek(long fp, int upto)
            {
                if (Debugging.AssertsEnabled) Debugging.Assert(upto < blockSize);
                if (seekPending || fp != lastBlockFP)
                {
                    pendingFP = fp;
                    seekPending = true;
                }
                this.upto = upto;
            }

            public override int Next()
            {
                if (seekPending)
                {
                    // Seek & load new block
                    input.Seek(pendingFP);
                    lastBlockFP = pendingFP;
                    blockReader.ReadBlock();
                    seekPending = false;
                }
                else if (upto == blockSize)
                {
                    // Load new block
                    lastBlockFP = input.GetFilePointer();
                    blockReader.ReadBlock();
                    upto = 0;
                }
                return pending[upto++];
            }
        }

        new private class Index : Int32IndexInput.Index
        {
            private readonly FixedInt32BlockIndexInput outerInstance;

            public Index(FixedInt32BlockIndexInput outerInstance)
            {
                this.outerInstance = outerInstance;
            }

            private long fp;
            private int upto;

            public override void Read(DataInput indexIn, bool absolute)
            {
                if (absolute)
                {
                    upto = indexIn.ReadVInt32();
                    fp = indexIn.ReadVInt64();
                }
                else
                {
                    int uptoDelta = indexIn.ReadVInt32();
                    if ((uptoDelta & 1) == 1)
                    {
                        // same block
                        upto += (int)((uint)uptoDelta >> 1);
                    }
                    else
                    {
                        // new block
                        upto = (int)((uint)uptoDelta >> 1);
                        fp += indexIn.ReadVInt64();
                    }
                }
                if (Debugging.AssertsEnabled) Debugging.Assert(upto < outerInstance.m_blockSize);
            }

            public override void Seek(Int32IndexInput.Reader other)
            {
                ((Reader)other).Seek(fp, upto);
            }

            public override void CopyFrom(Int32IndexInput.Index other)
            {
                Index idx = (Index)other;
                fp = idx.fp;
                upto = idx.upto;
            }

            public override object Clone()
            {
                Index other = new Index(outerInstance);
                other.fp = fp;
                other.upto = upto;
                return other;
            }

            public override string ToString()
            {
                return "fp=" + fp + " upto=" + upto;
            }
        }
    }
}