using J2N.Collections.Generic.Extensions;
using Lucene.Net.Diagnostics;
using Lucene.Net.Search;
using Lucene.Net.Search.Similarities;
using Lucene.Net.Util;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

namespace Lucene.Net.Index.Memory
{
    /*
     * 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 partial class MemoryIndex
    {
        ///////////////////////////////////////////////////////////////////////////////
        // Nested classes:
        ///////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Search support for Lucene framework integration; implements all methods
        /// required by the Lucene IndexReader contracts.
        /// </summary>
        private sealed class MemoryIndexReader : AtomicReader
        {
            private readonly MemoryIndex outerInstance;


            internal IndexSearcher searcher; // needed to find searcher.getSimilarity()

            internal MemoryIndexReader(MemoryIndex outerInstance)
                    : base() // avoid as much superclass baggage as possible
            {
                this.outerInstance = outerInstance;
            }

            internal Info GetInfo(string fieldName)
            {
                return outerInstance.fields[fieldName];
            }

            internal Info GetInfo(int pos)
            {
                return outerInstance.sortedFields[pos].Value;
            }

            public override IBits LiveDocs => null;

            public override FieldInfos FieldInfos => new FieldInfos(outerInstance.fieldInfos.Values.ToArray(/*new FieldInfo[outerInstance.fieldInfos.Count]*/));

            public override NumericDocValues GetNumericDocValues(string field)
            {
                return null;
            }

            public override BinaryDocValues GetBinaryDocValues(string field)
            {
                return null;
            }

            public override SortedDocValues GetSortedDocValues(string field)
            {
                return null;
            }

            public override SortedSetDocValues GetSortedSetDocValues(string field)
            {
                return null;
            }

            public override IBits GetDocsWithField(string field)
            {
                return null;
            }

            public override void CheckIntegrity()
            {
                // no-op
            }

            private class MemoryFields : Fields
            {
                private readonly MemoryIndex.MemoryIndexReader outerInstance;

                public MemoryFields(MemoryIndex.MemoryIndexReader outerInstance)
                {
                    this.outerInstance = outerInstance;
                }

                public override IEnumerator<string> GetEnumerator()
                {
                    return new IteratorAnonymousInnerClassHelper(this);
                }

                private class IteratorAnonymousInnerClassHelper : IEnumerator<string>
                {
                    private readonly MemoryFields outerInstance;

                    public IteratorAnonymousInnerClassHelper(MemoryFields outerInstance)
                    {
                        this.outerInstance = outerInstance;
                        upto = -1;
                    }

                    internal int upto;
                    private string current;

                    public string Current => this.current;

                    object IEnumerator.Current => Current;

                    public void Dispose()
                    {
                        // Nothing to do
                    }

                    public bool MoveNext()
                    {
                        if (upto + 1 >= outerInstance.outerInstance.outerInstance.sortedFields.Length)
                        {
                            return false;
                        }
                        upto++;
                        current = outerInstance.outerInstance.outerInstance.sortedFields[upto].Key;
                        return true;
                    }

                    public void Reset()
                    {
                        throw new NotSupportedException();
                    }
                }

                public override Terms GetTerms(string field)
                {
                    var searchField = new KeyValuePair<string, Info>(field, null);
                    int i = Array.BinarySearch(outerInstance.outerInstance.sortedFields, searchField, new TermComparer<string, Info>());
                    if (i < 0)
                    {
                        return null;
                    }
                    else
                    {
                        Info info = outerInstance.GetInfo(i);
                        info.SortTerms();

                        return new TermsAnonymousInnerClassHelper(this, info);
                    }
                }

                private class TermsAnonymousInnerClassHelper : Terms
                {
                    private readonly MemoryFields outerInstance;

                    private MemoryIndex.Info info;

                    public TermsAnonymousInnerClassHelper(MemoryFields outerInstance, MemoryIndex.Info info)
                    {
                        this.outerInstance = outerInstance;
                        this.info = info;
                    }

                    public override TermsEnum GetEnumerator()
                    {
                        return new MemoryTermsEnum(outerInstance.outerInstance, info);
                    }

                    public override IComparer<BytesRef> Comparer => BytesRef.UTF8SortedAsUnicodeComparer;

                    public override long Count => info.terms.Count;

                    public override long SumTotalTermFreq => info.SumTotalTermFreq;

                    public override long SumDocFreq =>
                        // each term has df=1
                        info.terms.Count;

                    public override int DocCount => info.terms.Count > 0 ? 1 : 0;

                    public override bool HasFreqs => true;

                    public override bool HasOffsets => outerInstance.outerInstance.outerInstance.storeOffsets;

                    public override bool HasPositions => true;

                    public override bool HasPayloads => false;
                }

                public override int Count => outerInstance.outerInstance.sortedFields.Length;
            }

            public override Fields Fields
            {
                get
                {
                    outerInstance.SortFields();
                    return new MemoryFields(this);
                }
            }

            private class MemoryTermsEnum : TermsEnum
            {
                private readonly MemoryIndex.MemoryIndexReader outerInstance;

                internal readonly Info info;
                internal readonly BytesRef br = new BytesRef();
                internal int termUpto = -1;

                public MemoryTermsEnum(MemoryIndex.MemoryIndexReader outerInstance, Info info)
                {
                    this.outerInstance = outerInstance;
                    this.info = info;
                    info.SortTerms();
                }

                internal int BinarySearch(BytesRef b, BytesRef bytesRef, int low, int high, BytesRefHash hash, int[] ords, IComparer<BytesRef> comparer)
                {
                    int mid = 0;
                    while (low <= high)
                    {
                        mid = (int)((uint)(low + high) >> 1);
                        hash.Get(ords[mid], bytesRef);
                        int cmp = comparer.Compare(bytesRef, b);
                        if (cmp < 0)
                        {
                            low = mid + 1;
                        }
                        else if (cmp > 0)
                        {
                            high = mid - 1;
                        }
                        else
                        {
                            return mid;
                        }
                    }
                    if (Debugging.AssertsEnabled) Debugging.Assert(comparer.Compare(bytesRef, b) != 0);
                    return -(low + 1);
                }


                public override bool SeekExact(BytesRef text)
                {
                    termUpto = BinarySearch(text, br, 0, info.terms.Count - 1, info.terms, info.sortedTerms, BytesRef.UTF8SortedAsUnicodeComparer);
                    return termUpto >= 0;
                }

                public override SeekStatus SeekCeil(BytesRef text)
                {
                    termUpto = BinarySearch(text, br, 0, info.terms.Count - 1, info.terms, info.sortedTerms, BytesRef.UTF8SortedAsUnicodeComparer);
                    if (termUpto < 0) // not found; choose successor
                    {
                        termUpto = -termUpto - 1;
                        if (termUpto >= info.terms.Count)
                        {
                            return SeekStatus.END;
                        }
                        else
                        {
                            info.terms.Get(info.sortedTerms[termUpto], br);
                            return SeekStatus.NOT_FOUND;
                        }
                    }
                    else
                    {
                        return SeekStatus.FOUND;
                    }
                }

                public override void SeekExact(long ord)
                {
                    if (Debugging.AssertsEnabled) Debugging.Assert(ord < info.terms.Count);
                    termUpto = (int)ord;
                }

                public override bool MoveNext()
                {
                    termUpto++;
                    if (termUpto >= info.terms.Count)
                    {
                        return false;
                    }
                    else
                    {
                        info.terms.Get(info.sortedTerms[termUpto], br);
                        return true;
                    }
                }

                [Obsolete("Use MoveNext() and Term instead. This method will be removed in 4.8.0 release candidate."), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
                public override BytesRef Next()
                {
                    if (MoveNext())
                        return br;
                    return null;
                }

                public override BytesRef Term => br;

                public override long Ord => termUpto;

                public override int DocFreq => 1;

                public override long TotalTermFreq => info.sliceArray.freq[info.sortedTerms[termUpto]];

                public override DocsEnum Docs(IBits liveDocs, DocsEnum reuse, DocsFlags flags)
                {
                    if (reuse is null || !(reuse is MemoryDocsEnum toReuse))
                        toReuse = new MemoryDocsEnum(outerInstance);

                    return toReuse.Reset(liveDocs, info.sliceArray.freq[info.sortedTerms[termUpto]]);
                }

                public override DocsAndPositionsEnum DocsAndPositions(IBits liveDocs, DocsAndPositionsEnum reuse, DocsAndPositionsFlags flags)
                {
                    if (reuse is null || !(reuse is MemoryDocsAndPositionsEnum toReuse))
                        toReuse = new MemoryDocsAndPositionsEnum(outerInstance);

                    int ord = info.sortedTerms[termUpto];
                    return toReuse.Reset(liveDocs, info.sliceArray.start[ord], info.sliceArray.end[ord], info.sliceArray.freq[ord]);
                }

                public override IComparer<BytesRef> Comparer => BytesRef.UTF8SortedAsUnicodeComparer;

                public override void SeekExact(BytesRef term, TermState state)
                {
                    if (Debugging.AssertsEnabled) Debugging.Assert(state != null);
                    this.SeekExact(((OrdTermState)state).Ord);
                }

                public override TermState GetTermState()
                {
                    OrdTermState ts = new OrdTermState();
                    ts.Ord = termUpto;
                    return ts;
                }
            }

            private class MemoryDocsEnum : DocsEnum
            {
                private readonly MemoryIndex.MemoryIndexReader outerInstance;

                public MemoryDocsEnum(MemoryIndex.MemoryIndexReader outerInstance)
                {
                    this.outerInstance = outerInstance;
                }

                internal bool hasNext;
                internal IBits liveDocs;
                internal int doc = -1;
                internal int freq;

                public virtual DocsEnum Reset(IBits liveDocs, int freq)
                {
                    this.liveDocs = liveDocs;
                    hasNext = true;
                    doc = -1;
                    this.freq = freq;
                    return this;
                }

                public override int DocID => doc;

                public override int NextDoc()
                {
                    if (hasNext && (liveDocs == null || liveDocs.Get(0)))
                    {
                        hasNext = false;
                        return doc = 0;
                    }
                    else
                    {
                        return doc = NO_MORE_DOCS;
                    }
                }

                public override int Advance(int target)
                {
                    return SlowAdvance(target);
                }

                public override int Freq => freq;

                public override long GetCost()
                {
                    return 1;
                }
            }

            private class MemoryDocsAndPositionsEnum : DocsAndPositionsEnum
            {
                private readonly MemoryIndex.MemoryIndexReader outerInstance;

                internal int posUpto; // for assert
                internal bool hasNext;
                internal IBits liveDocs;
                internal int doc = -1;
                internal Int32BlockPool.SliceReader sliceReader;
                internal int freq;
                internal int startOffset;
                internal int endOffset;

                public MemoryDocsAndPositionsEnum(MemoryIndex.MemoryIndexReader outerInstance)
                {
                    this.outerInstance = outerInstance;
                    this.sliceReader = new Int32BlockPool.SliceReader(outerInstance.outerInstance.intBlockPool);
                }

                public virtual DocsAndPositionsEnum Reset(IBits liveDocs, int start, int end, int freq)
                {
                    this.liveDocs = liveDocs;
                    this.sliceReader.Reset(start, end);
                    posUpto = 0; // for assert
                    hasNext = true;
                    doc = -1;
                    this.freq = freq;
                    return this;
                }


                public override int DocID => doc;

                public override int NextDoc()
                {
                    if (hasNext && (liveDocs == null || liveDocs.Get(0)))
                    {
                        hasNext = false;
                        return doc = 0;
                    }
                    else
                    {
                        return doc = NO_MORE_DOCS;
                    }
                }

                public override int Advance(int target)
                {
                    return SlowAdvance(target);
                }

                public override int Freq => freq;

                public override int NextPosition()
                {
                    if (Debugging.AssertsEnabled)
                    {
                        Debugging.Assert(posUpto++ < freq);
                        Debugging.Assert(!sliceReader.IsEndOfSlice, () => " stores offsets : " + startOffset);
                    }
                    if (outerInstance.outerInstance.storeOffsets)
                    {
                        int pos = sliceReader.ReadInt32();
                        startOffset = sliceReader.ReadInt32();
                        endOffset = sliceReader.ReadInt32();
                        return pos;
                    }
                    else
                    {
                        return sliceReader.ReadInt32();
                    }
                }

                public override int StartOffset => startOffset;

                public override int EndOffset => endOffset;

                public override BytesRef GetPayload()
                {
                    return null;
                }

                public override long GetCost()
                {
                    return 1;
                }
            }

            public override Fields GetTermVectors(int docID)
            {
                if (docID == 0)
                {
                    return Fields;
                }
                else
                {
                    return null;
                }
            }

            internal Similarity Similarity
            {
                get
                {
                    if (searcher != null)
                    {
                        return searcher.Similarity;
                    }
                    return IndexSearcher.DefaultSimilarity;
                }
            }

            internal IndexSearcher Searcher
            {
                get => this.searcher; // LUCENENET specific: added getter per MSDN guidelines
                set => this.searcher = value;
            }

            public override int NumDocs
            {
                get
                {
#if DEBUG
                    Debug.WriteLine("MemoryIndexReader.NumDocs");
#endif
                    return 1;
                }
            }

            public override int MaxDoc
            {
                get
                {
#if DEBUG
                    Debug.WriteLine("MemoryIndexReader.MaxDoc");
#endif
                    return 1;
                }
            }

            public override void Document(int docID, StoredFieldVisitor visitor)
            {
#if DEBUG
                Debug.WriteLine("MemoryIndexReader.Document");
#endif
                // no-op: there are no stored fields
            }
            protected internal override void DoClose()
            {
#if DEBUG
                Debug.WriteLine("MemoryIndexReader.DoClose");
#endif
            }

            /// <summary>
            /// performance hack: cache norms to avoid repeated expensive calculations </summary>
            internal NumericDocValues cachedNormValues;
            internal string cachedFieldName;
            internal Similarity cachedSimilarity;

            public override NumericDocValues GetNormValues(string field)
            {
                FieldInfo fieldInfo;
                if (!outerInstance.fieldInfos.TryGetValue(field, out fieldInfo) || fieldInfo.OmitsNorms)
                {
                    return null;
                }
                NumericDocValues norms = cachedNormValues;
                Similarity sim = Similarity;
                if (!field.Equals(cachedFieldName, StringComparison.Ordinal) || sim != cachedSimilarity) // not cached?
                {
                    Info info = GetInfo(field);
                    int numTokens = info != null ? info.numTokens : 0;
                    int numOverlapTokens = info != null ? info.numOverlapTokens : 0;
                    float boost = info != null ? info.Boost : 1.0f;
                    FieldInvertState invertState = new FieldInvertState(field, 0, numTokens, numOverlapTokens, 0, boost);
                    long value = sim.ComputeNorm(invertState);
                    norms = new MemoryIndexNormDocValues(value);
                    // cache it for future reuse
                    cachedNormValues = norms;
                    cachedFieldName = field;
                    cachedSimilarity = sim;
#if DEBUG
                    Debug.WriteLine("MemoryIndexReader.norms: " + field + ":" + value + ":" + numTokens);
#endif
                }
                return norms;
            }
        }
    }
}
