﻿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>
            public Docs()
            {
            }

            /// <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();
            }
        }
    }
}