﻿using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Support;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace Lucene.Net.Facet
{
    /*
     * 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>
    /// Collects hits for subsequent faceting.  Once you've run
    /// a search and collect hits into this, instantiate one of
    /// the <see cref="ICollector"/> subclasses to do the facet
    /// counting.  Use the Search utility methods (such as <see cref="Search(IndexSearcher, Query, int, ICollector)"/>) to
    /// perform an "ordinary" search but also collect into a
    /// <see cref="Facets"/>. 
    /// </summary>
    public class FacetsCollector : ICollector
    {
        private AtomicReaderContext context;
        private Scorer scorer;
        private int totalHits;
        private float[] scores;
        private readonly bool keepScores;
        private readonly List<MatchingDocs> matchingDocs = new List<MatchingDocs>();
        private Docs docs;

        /// <summary>
        /// Used during collection to record matching docs and then return a
        /// <see cref="DocIdSet"/> that contains them.
        /// </summary>
        protected abstract class Docs
        {

            /// <summary>
            /// Sole constructor.
            /// </summary>
            protected Docs() // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
            {
            }

            /// <summary>
            /// Record the given document.
            /// </summary>
            public abstract void AddDoc(int docId);

            /// <summary>
            /// Return the <see cref="DocIdSet"/> which contains all the recorded docs.
            /// </summary>
            public abstract DocIdSet DocIdSet { get; }
        }

        /// <summary>
        /// Holds the documents that were matched in the <see cref="AtomicReaderContext"/>.
        /// If scores were required, then <see cref="Scores"/> is not <c>null</c>.
        /// </summary>
        public sealed class MatchingDocs
        {
            /// <summary>
            /// Context for this segment. </summary>
            public AtomicReaderContext Context { get; private set; }

            /// <summary>
            /// Which documents were seen. </summary>
            public DocIdSet Bits { get; private set; }

            /// <summary>
            /// Non-sparse scores array. </summary>
            [WritableArray]
            [SuppressMessage("Microsoft.Performance", "CA1819", Justification = "Lucene's design requires some writable array properties")]
            public float[] Scores { get; private set; }

            /// <summary>
            /// Total number of hits </summary>
            public int TotalHits { get; private set; }

            /// <summary>
            /// Sole constructor.
            /// </summary>
            public MatchingDocs(AtomicReaderContext context, DocIdSet bits, int totalHits, float[] scores)
            {
                this.Context = context;
                this.Bits = bits;
                this.Scores = scores;
                this.TotalHits = totalHits;
            }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public FacetsCollector()
            : this(false)
        {
        }

        /// <summary>
        /// Create this; if <paramref name="keepScores"/> is <c>true</c> then a
        /// <see cref="T:float[]"/> is allocated to hold score of all hits. 
        /// </summary>
        public FacetsCollector(bool keepScores)
        {
            this.keepScores = keepScores;
        }

        /// <summary>
        /// Creates a <see cref="Docs"/> to record hits. The default uses <see cref="FixedBitSet"/>
        /// to record hits and you can override to e.g. record the docs in your own
        /// <see cref="DocIdSet"/>.
        /// </summary>
        protected virtual Docs CreateDocs(int maxDoc)
        {
            return new DocsAnonymousInnerClassHelper(maxDoc);
        }

        private class DocsAnonymousInnerClassHelper : Docs
        {
            public DocsAnonymousInnerClassHelper(int maxDoc)
            {
                bits = new FixedBitSet(maxDoc);
            }

            private readonly FixedBitSet bits;

            public override void AddDoc(int docId)
            {
                bits.Set(docId);
            }

            public override DocIdSet DocIdSet => bits;
        }

        /// <summary>
        /// True if scores were saved.
        /// </summary>
        public bool KeepScores => keepScores;

        /// <summary>
        /// Returns the documents matched by the query, one <see cref="MatchingDocs"/> per
        /// visited segment.
        /// </summary>
        public virtual IList<MatchingDocs> GetMatchingDocs()
        {
            if (docs != null)
            {
                matchingDocs.Add(new MatchingDocs(this.context, docs.DocIdSet, totalHits, scores));
                docs = null;
                scores = null;
                context = null;
            }

            return matchingDocs;
        }

        public bool AcceptsDocsOutOfOrder =>
            // If we are keeping scores then we require in-order
            // because we append each score to the float[] and
            // expect that they correlate in order to the hits:
            keepScores == false;

        public void Collect(int doc)
        {
            docs.AddDoc(doc);
            if (keepScores)
            {
                if (totalHits >= scores.Length)
                {
                    float[] newScores = new float[ArrayUtil.Oversize(totalHits + 1, 4)];
                    Array.Copy(scores, 0, newScores, 0, totalHits);
                    scores = newScores;
                }
                scores[totalHits] = scorer.GetScore();
            }
            totalHits++;
        }

        public void SetScorer(Scorer scorer)
        {
            this.scorer = scorer;
        }

        public void SetNextReader(AtomicReaderContext context)
        {
            if (docs != null)
            {
                matchingDocs.Add(new MatchingDocs(this.context, docs.DocIdSet, totalHits, scores));
            }
            docs = CreateDocs(context.Reader.MaxDoc);
            totalHits = 0;
            if (keepScores)
            {
                scores = new float[64]; // some initial size
            }
            this.context = context;
        }

        /// <summary>
        /// Utility method, to search and also collect all hits
        /// into the provided <see cref="ICollector"/>. 
        /// </summary>
        public static TopDocs Search(IndexSearcher searcher, Query q, int n, ICollector fc)
        {
            return DoSearch(searcher, null, q, null, n, null, false, false, fc);
        }

        /// <summary>
        /// Utility method, to search and also collect all hits
        /// into the provided <see cref="ICollector"/>. 
        /// </summary>
        public static TopDocs Search(IndexSearcher searcher, Query q, Filter filter, int n, ICollector fc)
        {
            return DoSearch(searcher, null, q, filter, n, null, false, false, fc);
        }

        /// <summary>
        /// Utility method, to search and also collect all hits
        /// into the provided <see cref="ICollector"/>. 
        /// </summary>
        public static TopFieldDocs Search(IndexSearcher searcher, Query q, Filter filter, int n, Sort sort, ICollector fc)
        {
            if (sort == null)
            {
                throw new ArgumentException("sort must not be null");
            }
            return (TopFieldDocs)DoSearch(searcher, null, q, filter, n, sort, false, false, fc);
        }

        /// <summary>
        /// Utility method, to search and also collect all hits
        /// into the provided <see cref="ICollector"/>. 
        /// </summary>
        public static TopFieldDocs Search(IndexSearcher searcher, Query q, Filter filter, int n, Sort sort, bool doDocScores, bool doMaxScore, ICollector fc)
        {
            if (sort == null)
            {
                throw new ArgumentException("sort must not be null");
            }
            return (TopFieldDocs)DoSearch(searcher, null, q, filter, n, sort, doDocScores, doMaxScore, fc);
        }

        /// <summary>
        /// Utility method, to search and also collect all hits
        /// into the provided <see cref="ICollector"/>. 
        /// </summary>
        public virtual TopDocs SearchAfter(IndexSearcher searcher, ScoreDoc after, Query q, int n, ICollector fc)
        {
            return DoSearch(searcher, after, q, null, n, null, false, false, fc);
        }

        /// <summary>
        /// Utility method, to search and also collect all hits
        /// into the provided <see cref="ICollector"/>. 
        /// </summary>
        public static TopDocs SearchAfter(IndexSearcher searcher, ScoreDoc after, Query q, Filter filter, int n, ICollector fc)
        {
            return DoSearch(searcher, after, q, filter, n, null, false, false, fc);
        }

        /// <summary>
        /// Utility method, to search and also collect all hits
        /// into the provided <see cref="ICollector"/>. 
        /// </summary>
        public static TopDocs SearchAfter(IndexSearcher searcher, ScoreDoc after, Query q, Filter filter, int n, Sort sort, ICollector fc)
        {
            if (sort == null)
            {
                throw new ArgumentException("sort must not be null");
            }
            return DoSearch(searcher, after, q, filter, n, sort, false, false, fc);
        }

        /// <summary>
        /// Utility method, to search and also collect all hits
        /// into the provided <see cref="ICollector"/>. 
        /// </summary>
        public static TopDocs SearchAfter(IndexSearcher searcher, ScoreDoc after, Query q, Filter filter, int n, Sort sort, bool doDocScores, bool doMaxScore, ICollector fc)
        {
            if (sort == null)
            {
                throw new ArgumentException("sort must not be null");
            }
            return DoSearch(searcher, after, q, filter, n, sort, doDocScores, doMaxScore, fc);
        }

        private static TopDocs DoSearch(IndexSearcher searcher, ScoreDoc after, Query q, Filter filter, int n, Sort sort, bool doDocScores, bool doMaxScore, ICollector fc)
        {

            if (filter != null)
            {
                q = new FilteredQuery(q, filter);
            }

            int limit = searcher.IndexReader.MaxDoc;
            if (limit == 0)
            {
                limit = 1;
            }
            n = Math.Min(n, limit);

            if (after != null && after.Doc >= limit)
            {
                throw new ArgumentException("after.doc exceeds the number of documents in the reader: after.doc=" + after.Doc + " limit=" + limit);
            }


            if (sort != null)
            {
                if (after != null && !(after is FieldDoc))
                {
                    // TODO: if we fix type safety of TopFieldDocs we can
                    // remove this
                    throw new ArgumentException("after must be a FieldDoc; got " + after);
                }
                const bool fillFields = true;
                var hitsCollector = TopFieldCollector.Create(sort, n, (FieldDoc)after, fillFields, doDocScores, doMaxScore, false);
                searcher.Search(q, MultiCollector.Wrap(hitsCollector, fc));
                return hitsCollector.GetTopDocs();
            }
            else
            {
                // TODO: can we pass the right boolean for
                // in-order instead of hardwired to false...?  we'd
                // need access to the protected IS.search methods
                // taking Weight... could use reflection...
                var hitsCollector = TopScoreDocCollector.Create(n, after, false);
                searcher.Search(q, MultiCollector.Wrap(hitsCollector, fc));
                return hitsCollector.GetTopDocs();
            }
        }
    }
}