﻿using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Store;
using Lucene.Net.Support;
using System.Diagnostics;
using System.IO;

namespace Lucene.Net.Codecs.Sep
{
    /*
     * 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>
    /// Implements the skip list reader for the default posting list format
    /// that stores positions and payloads.
    /// <para/>
    /// @lucene.experimental
    /// </summary>

    // TODO: rewrite this as recursive classes?
    internal class SepSkipListReader : MultiLevelSkipListReader
    {
        private bool currentFieldStoresPayloads;
        private Int32IndexInput.Index[] freqIndex;
        private Int32IndexInput.Index[] docIndex;
        private Int32IndexInput.Index[] posIndex;
        private long[] payloadPointer;
        private int[] payloadLength;

        private readonly Int32IndexInput.Index lastFreqIndex;
        private readonly Int32IndexInput.Index lastDocIndex;
        // TODO: -- make private again
        internal readonly Int32IndexInput.Index lastPosIndex;

        private long lastPayloadPointer;
        private int lastPayloadLength;

        /// <exception cref="IOException"/>
        internal SepSkipListReader(IndexInput skipStream,
                          Int32IndexInput freqIn,
                          Int32IndexInput docIn,
                          Int32IndexInput posIn,
                          int maxSkipLevels,
                          int skipInterval)
            : base(skipStream, maxSkipLevels, skipInterval)
        {
            if (freqIn != null)
            {
                freqIndex = new Int32IndexInput.Index[maxSkipLevels];
            }
            docIndex = new Int32IndexInput.Index[maxSkipLevels];
            if (posIn != null)
            {
                posIndex = new Int32IndexInput.Index[m_maxNumberOfSkipLevels];
            }
            for (int i = 0; i < maxSkipLevels; i++)
            {
                if (freqIn != null)
                {
                    freqIndex[i] = freqIn.GetIndex();
                }
                docIndex[i] = docIn.GetIndex();
                if (posIn != null)
                {
                    posIndex[i] = posIn.GetIndex();
                }
            }
            payloadPointer = new long[maxSkipLevels];
            payloadLength = new int[maxSkipLevels];

            if (freqIn != null)
            {
                lastFreqIndex = freqIn.GetIndex();
            }
            else
            {
                lastFreqIndex = null;
            }
            lastDocIndex = docIn.GetIndex();
            if (posIn != null)
            {
                lastPosIndex = posIn.GetIndex();
            }
            else
            {
                lastPosIndex = null;
            }
        }

        internal IndexOptions indexOptions;

        internal void SetIndexOptions(IndexOptions v)
        {
            indexOptions = v;
        }

        internal void Init(long skipPointer,
                  Int32IndexInput.Index docBaseIndex,
                  Int32IndexInput.Index freqBaseIndex,
                  Int32IndexInput.Index posBaseIndex,
                  long payloadBasePointer,
                  int df,
                  bool storesPayloads)
        {

            base.Init(skipPointer, df);
            this.currentFieldStoresPayloads = storesPayloads;

            lastPayloadPointer = payloadBasePointer;

            for (int i = 0; i < m_maxNumberOfSkipLevels; i++)
            {
                docIndex[i].CopyFrom(docBaseIndex);
                if (freqIndex != null)
                {
                    freqIndex[i].CopyFrom(freqBaseIndex);
                }
                if (posBaseIndex != null)
                {
                    posIndex[i].CopyFrom(posBaseIndex);
                }
            }
            Arrays.Fill(payloadPointer, payloadBasePointer);
            Arrays.Fill(payloadLength, 0);
        }

        internal long PayloadPointer => lastPayloadPointer;

        /// <summary>
        /// Returns the payload length of the payload stored just before 
        /// the doc to which the last call of <see cref="MultiLevelSkipListReader.SkipTo(int)"/> 
        /// has skipped.
        /// </summary>
        internal int PayloadLength => lastPayloadLength;

        /// <exception cref="IOException"/>
        protected override void SeekChild(int level)
        {
            base.SeekChild(level);
            payloadPointer[level] = lastPayloadPointer;
            payloadLength[level] = lastPayloadLength;
        }

        protected override void SetLastSkipData(int level)
        {
            base.SetLastSkipData(level);

            lastPayloadPointer = payloadPointer[level];
            lastPayloadLength = payloadLength[level];
            if (freqIndex != null)
            {
                lastFreqIndex.CopyFrom(freqIndex[level]);
            }
            lastDocIndex.CopyFrom(docIndex[level]);
            if (lastPosIndex != null)
            {
                lastPosIndex.CopyFrom(posIndex[level]);
            }

            if (level > 0)
            {
                if (freqIndex != null)
                {
                    freqIndex[level - 1].CopyFrom(freqIndex[level]);
                }
                docIndex[level - 1].CopyFrom(docIndex[level]);
                if (posIndex != null)
                {
                    posIndex[level - 1].CopyFrom(posIndex[level]);
                }
            }
        }

        internal Int32IndexInput.Index FreqIndex => lastFreqIndex;

        internal Int32IndexInput.Index PosIndex => lastPosIndex;

        internal Int32IndexInput.Index DocIndex => lastDocIndex;

        /// <exception cref="IOException"/>
        protected override int ReadSkipData(int level, IndexInput skipStream)
        {
            int delta;
            if (Debugging.AssertsEnabled) Debugging.Assert(indexOptions == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS || !currentFieldStoresPayloads);
            if (currentFieldStoresPayloads)
            {
                // the current field stores payloads.
                // if the doc delta is odd then we have
                // to read the current payload length
                // because it differs from the length of the
                // previous payload
                delta = skipStream.ReadVInt32();
                if ((delta & 1) != 0)
                {
                    payloadLength[level] = skipStream.ReadVInt32();
                }
                //delta >>>= 1;
                delta = (int)((uint)delta >> 1);
            }
            else
            {
                delta = skipStream.ReadVInt32();
            }
            if (indexOptions != IndexOptions.DOCS_ONLY)
            {
                freqIndex[level].Read(skipStream, false);
            }
            docIndex[level].Read(skipStream, false);
            if (indexOptions == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS)
            {
                posIndex[level].Read(skipStream, false);
                if (currentFieldStoresPayloads)
                {
                    payloadPointer[level] += skipStream.ReadVInt32();
                }
            }

            return delta;
        }
    }
}