﻿using System.Collections.Generic;
using Lucene.Net.Facet;

namespace Lucene.Net.Facet.Range
{

    /*
     * 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.
     */


    using MatchingDocs = FacetsCollector.MatchingDocs;
    using FunctionValues = Lucene.Net.Queries.Function.FunctionValues;
    using ValueSource = Lucene.Net.Queries.Function.ValueSource;
    using LongFieldSource = Lucene.Net.Queries.Function.ValueSources.LongFieldSource;
    using DocIdSet = Lucene.Net.Search.DocIdSet;
    using Filter = Lucene.Net.Search.Filter;
    using Bits = Lucene.Net.Util.Bits;
    using DocIdSetIterator = Lucene.Net.Search.DocIdSetIterator;

    /// <summary>
    /// <seealso cref="Facets"/> implementation that computes counts for
    ///  dynamic long ranges from a provided <seealso cref="ValueSource"/>,
    ///  using <seealso cref="FunctionValues#longVal"/>.  Use
    ///  this for dimensions that change in real-time (e.g. a
    ///  relative time based dimension like "Past day", "Past 2
    ///  days", etc.) or that change for each request (e.g. 
    ///  distance from the user's location, "< 1 km", "< 2 km",
    ///  etc.).
    /// 
    ///  @lucene.experimental 
    /// </summary>
    public class LongRangeFacetCounts : RangeFacetCounts
    {

        /// <summary>
        /// Create {@code LongRangeFacetCounts}, using {@link
        ///  LongFieldSource} from the specified field. 
        /// </summary>
        public LongRangeFacetCounts(string field, FacetsCollector hits, params LongRange[] ranges)
            : this(field, new LongFieldSource(field), hits, ranges)
        {
        }

        /// <summary>
        /// Create {@code RangeFacetCounts}, using the provided
        ///  <seealso cref="ValueSource"/>. 
        /// </summary>
        public LongRangeFacetCounts(string field, ValueSource valueSource, FacetsCollector hits, params LongRange[] ranges)
            : this(field, valueSource, hits, null, ranges)
        {
        }

        /// <summary>
        /// Create {@code RangeFacetCounts}, using the provided
        ///  <seealso cref="ValueSource"/>, and using the provided Filter as
        ///  a fastmatch: only documents passing the filter are
        ///  checked for the matching ranges.  The filter must be
        ///  random access (implement <seealso cref="DocIdSet#bits"/>). 
        /// </summary>
        public LongRangeFacetCounts(string field, ValueSource valueSource, FacetsCollector hits, Filter fastMatchFilter, params LongRange[] ranges)
            : base(field, ranges, fastMatchFilter)
        {
            Count(valueSource, hits.GetMatchingDocs);
        }

        private void Count(ValueSource valueSource, IList<MatchingDocs> matchingDocs)
        {

            LongRange[] ranges = (LongRange[])this.Ranges;

            LongRangeCounter counter = new LongRangeCounter(ranges);

            int missingCount = 0;
            foreach (MatchingDocs hits in matchingDocs)
            {
                FunctionValues fv = valueSource.GetValues(new Dictionary<string, object>(), hits.context);

                TotCount += hits.totalHits;
                Bits bits;
                if (FastMatchFilter != null)
                {
                    DocIdSet dis = FastMatchFilter.GetDocIdSet(hits.context, null);
                    if (dis == null)
                    {
                        // No documents match
                        continue;
                    }
                    bits = dis.GetBits();
                    if (bits == null)
                    {
                        throw new System.ArgumentException("fastMatchFilter does not implement DocIdSet.bits");
                    }
                }
                else
                {
                    bits = null;
                }

                DocIdSetIterator docs = hits.bits.GetIterator();
                int doc;
                while ((doc = docs.NextDoc()) != DocIdSetIterator.NO_MORE_DOCS)
                {
                    if (bits != null && bits.Get(doc) == false)
                    {
                        doc++;
                        continue;
                    }
                    // Skip missing docs:
                    if (fv.Exists(doc))
                    {
                        counter.add(fv.LongVal(doc));
                    }
                    else
                    {
                        missingCount++;
                    }
                }
            }

            int x = counter.fillCounts(Counts);

            missingCount += x;

            //System.out.println("totCount " + totCount + " missingCount " + counter.missingCount);
            TotCount -= missingCount;
        }
    }

}