﻿using Lucene.Net.Index;
using Lucene.Net.Util;
using System.Collections.Generic;
using System.IO;

namespace Lucene.Net.Search.Grouping
{
    /*
     * 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>
    /// This collector specializes in collecting the most relevant document (group head) for each group that match the query.
    /// 
    /// @lucene.experimental
    /// </summary>
    /// <typeparam name="GH"></typeparam>
    public abstract class AbstractAllGroupHeadsCollector<GH> : AbstractAllGroupHeadsCollector
        where GH : AbstractAllGroupHeadsCollector_GroupHead
    {
        protected readonly int[] m_reversed;
        protected readonly int m_compIDXEnd;
        protected readonly TemporalResult m_temporalResult;

        protected AbstractAllGroupHeadsCollector(int numberOfSorts)
        {
            this.m_reversed = new int[numberOfSorts];
            this.m_compIDXEnd = numberOfSorts - 1;
            m_temporalResult = new TemporalResult();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="maxDoc">The maxDoc of the top level <see cref="Index.IndexReader"/></param>
        /// <returns>a <see cref="FixedBitSet"/> containing all group heads.</returns>
        public override FixedBitSet RetrieveGroupHeads(int maxDoc)
        {
            FixedBitSet bitSet = new FixedBitSet(maxDoc);

            ICollection<GH> groupHeads = CollectedGroupHeads;
            foreach (GH groupHead in groupHeads)
            {
                bitSet.Set(groupHead.Doc);
            }

            return bitSet;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns>an int array containing all group heads. The size of the array is equal to number of collected unique groups.</returns>
        public override int[] RetrieveGroupHeads()
        {
            ICollection<GH> groupHeads = CollectedGroupHeads;
            int[] docHeads = new int[groupHeads.Count];

            int i = 0;
            foreach (GH groupHead in groupHeads)
            {
                docHeads[i++] = groupHead.Doc;
            }

            return docHeads;
        }

        /// <summary>
        /// The number of group heads found for a query.
        /// LUCENENET NOTE: This was groupHeadsSize() in Lucene
        /// </summary>
        /// <returns>the number of group heads found for a query.</returns>
        public override int GroupHeadsCount => CollectedGroupHeads.Count;

        /// <summary>
        /// Returns the group head and puts it into <see cref="TemporalResult"/>.
        /// If the group head wasn't encountered before then it will be added to the collected group heads.
        /// <para>
        /// The <see cref="TemporalResult.Stop"/> property will be <c>true</c> if the group head wasn't encountered before
        /// otherwise <c>false</c>.
        /// </para>
        /// </summary>
        /// <param name="doc">The document to retrieve the group head for.</param>
        /// <exception cref="IOException">If I/O related errors occur</exception>
        protected override abstract void RetrieveGroupHeadAndAddIfNotExist(int doc);

        /// <summary>
        /// Returns the collected group heads.
        /// Subsequent calls should return the same group heads.
        /// </summary>
        /// <returns>the collected group heads</returns>
        protected abstract ICollection<GH> CollectedGroupHeads { get; }

        public override void Collect(int doc)
        {
            RetrieveGroupHeadAndAddIfNotExist(doc);
            if (m_temporalResult.Stop)
            {
                return;
            }
            GH groupHead = m_temporalResult.GroupHead;

            // Ok now we need to check if the current doc is more relevant then current doc for this group
            for (int compIDX = 0; ; compIDX++)
            {
                int c = m_reversed[compIDX] * groupHead.Compare(compIDX, doc);
                if (c < 0)
                {
                    // Definitely not competitive. So don't even bother to continue
                    return;
                }
                else if (c > 0)
                {
                    // Definitely competitive.
                    break;
                }
                else if (compIDX == m_compIDXEnd)
                {
                    // Here c=0. If we're at the last comparer, this doc is not
                    // competitive, since docs are visited in doc Id order, which means
                    // this doc cannot compete with any other document in the queue.
                    return;
                }
            }
            groupHead.UpdateDocHead(doc);
        }

        public override bool AcceptsDocsOutOfOrder => false;

        /// <summary>
        /// Contains the result of group head retrieval.
        /// To prevent new object creations of this class for every collect.
        /// </summary>
        protected class TemporalResult
        {
            public GH GroupHead { get; set; }
            public bool Stop { get; set; }
        }
    }

    /// <summary>
    /// Represents a group head. A group head is the most relevant document for a particular group.
    /// The relevancy is based is usually based on the sort.
    /// <para>
    /// The group head contains a group value with its associated most relevant document id.
    /// </para>
    /// </summary>
    /// <remarks>
    /// LUCENENET: moved this class from being a nested class of <see cref="AbstractAllGroupHeadsCollector{TGroupValue}"/>,
    /// made it non-generic so the generic closing type doesn't need to be specified in classes that
    /// use <see cref="AbstractAllGroupHeadsCollector_GroupHead"/> as a generic closing type, and renamed 
    /// it from GroupHead to <see cref="AbstractAllGroupHeadsCollector_GroupHead"/> to avoid naming conflicts with nested classes 
    /// named GroupHead in derived classes of <see cref="AbstractAllGroupHeadsCollector"/>.
    /// </remarks>
    public abstract class AbstractAllGroupHeadsCollector_GroupHead /*<TGroupValue>*/
    {

        //public readonly TGroupValue groupValue;
        public int Doc { get; protected set; }

        protected AbstractAllGroupHeadsCollector_GroupHead(/*TGroupValue groupValue,*/ int doc)
        {
            //this.groupValue = groupValue;
            this.Doc = doc;
        }

        /// <summary>
        /// Compares the specified document for a specified comparer against the current most relevant document.
        /// </summary>
        /// <param name="compIDX">The comparer index of the specified comparer.</param>
        /// <param name="doc">The specified document.</param>
        /// <returns>
        /// -1 if the specified document wasn't competitive against the current most relevant document, 1 if the
        /// specified document was competitive against the current most relevant document. Otherwise 0.
        /// </returns>
        /// <exception cref="IOException">If I/O related errors occur</exception>
        public abstract int Compare(int compIDX, int doc);

        /// <summary>
        /// Updates the current most relevant document with the specified document.
        /// </summary>
        /// <param name="doc">The specified document</param>
        /// <exception cref="IOException">If I/O related errors occur</exception>
        public abstract void UpdateDocHead(int doc);
    }

    /// <summary>
    /// LUCENENET specific class used to reference an 
    /// <see cref="AbstractAllGroupHeadsCollector{GH}"/> subclass
    /// without refering to its generic closing type.
    /// </summary>
    public abstract class AbstractAllGroupHeadsCollector : ICollector
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="maxDoc">The maxDoc of the top level <see cref="Index.IndexReader"/></param>
        /// <returns>a <see cref="FixedBitSet"/> containing all group heads.</returns>
        public abstract FixedBitSet RetrieveGroupHeads(int maxDoc);

        /// <summary>
        /// 
        /// </summary>
        /// <returns>an int array containing all group heads. The size of the array is equal to number of collected unique groups.</returns>
        public abstract int[] RetrieveGroupHeads();

        /// <summary>
        /// The number of group heads found for a query.
        /// LUCENENET NOTE: This was groupHeadsSize() in Lucene
        /// </summary>
        /// <returns>the number of group heads found for a query.</returns>
        public abstract int GroupHeadsCount { get; }

        /// <summary>
        /// Returns the group head and puts it into <see cref="AbstractAllGroupHeadsCollector{GH}.TemporalResult"/>.
        /// If the group head wasn't encountered before then it will be added to the collected group heads.
        /// <para>
        /// The <see cref="AbstractAllGroupHeadsCollector{GH}.TemporalResult.Stop"/> property will be <c>true</c> if the group head wasn't encountered before
        /// otherwise <c>false</c>.
        /// </para>
        /// </summary>
        /// <param name="doc">The document to retrieve the group head for.</param>
        /// <exception cref="IOException">If I/O related errors occur</exception>
        protected abstract void RetrieveGroupHeadAndAddIfNotExist(int doc);


        // LUCENENET specific - we need to implement these here, since our abstract base class
        // is now an interface.
        /// <summary>
        /// Called before successive calls to <see cref="Collect(int)"/>. Implementations
        /// that need the score of the current document (passed-in to
        /// <also cref="Collect(int)"/>), should save the passed-in <see cref="Scorer"/> and call
        /// scorer.Score() when needed.
        /// </summary>
        public abstract void SetScorer(Scorer scorer);

        /// <summary>
        /// Called once for every document matching a query, with the unbased document
        /// number.
        /// <para/>Note: The collection of the current segment can be terminated by throwing
        /// a <see cref="CollectionTerminatedException"/>. In this case, the last docs of the
        /// current <see cref="AtomicReaderContext"/> will be skipped and <see cref="IndexSearcher"/>
        /// will swallow the exception and continue collection with the next leaf.
        /// <para/>
        /// Note: this is called in an inner search loop. For good search performance,
        /// implementations of this method should not call <see cref="IndexSearcher.Doc(int)"/> or
        /// <see cref="Lucene.Net.Index.IndexReader.Document(int)"/> on every hit.
        /// Doing so can slow searches by an order of magnitude or more.
        /// </summary>
        public abstract void Collect(int doc);

        /// <summary>
        /// Called before collecting from each <see cref="AtomicReaderContext"/>. All doc ids in
        /// <see cref="Collect(int)"/> will correspond to <see cref="Index.IndexReaderContext.Reader"/>.
        ///
        /// Add <see cref="AtomicReaderContext.DocBase"/> to the current <see cref="Index.IndexReaderContext.Reader"/>'s
        /// internal document id to re-base ids in <see cref="Collect(int)"/>.
        /// </summary>
        /// <param name="context">next atomic reader context </param>
        public abstract void SetNextReader(AtomicReaderContext context);

        /// <summary>
        /// Return <c>true</c> if this collector does not
        /// require the matching docIDs to be delivered in int sort
        /// order (smallest to largest) to <see cref="Collect"/>.
        ///
        /// <para> Most Lucene Query implementations will visit
        /// matching docIDs in order.  However, some queries
        /// (currently limited to certain cases of <see cref="BooleanQuery"/>) 
        /// can achieve faster searching if the
        /// <see cref="ICollector"/> allows them to deliver the
        /// docIDs out of order.</para>
        ///
        /// <para> Many collectors don't mind getting docIDs out of
        /// order, so it's important to return <c>true</c>
        /// here.</para>
        /// </summary>
        public abstract bool AcceptsDocsOutOfOrder { get; }
    }
}
