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

namespace Lucene.Net.Facet.SortedSet
{
    /*
     * 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>
    /// Default implementation of <see cref="SortedSetDocValuesFacetCounts"/>
    /// </summary>
    public class DefaultSortedSetDocValuesReaderState : SortedSetDocValuesReaderState
    {
        private readonly string field;
        private readonly AtomicReader topReader;
        private readonly int valueCount;

        /// <summary>
        /// <see cref="IndexReader"/> passed to the constructor. </summary>
        private readonly IndexReader origReader;

        private readonly IDictionary<string, OrdRange> prefixToOrdRange = new Dictionary<string, OrdRange>();

        /// <summary>
        /// Creates this, pulling doc values from the specified
        /// field. 
        /// </summary>
        public DefaultSortedSetDocValuesReaderState(IndexReader reader, string field = FacetsConfig.DEFAULT_INDEX_FIELD_NAME)
        {
            this.field = field;
            this.origReader = reader;

            // We need this to create thread-safe MultiSortedSetDV
            // per collector:
            topReader = SlowCompositeReaderWrapper.Wrap(reader);
            SortedSetDocValues dv = topReader.GetSortedSetDocValues(field);
            if (dv == null)
            {
                throw new ArgumentException("field \"" + field + "\" was not indexed with SortedSetDocValues");
            }
            if (dv.ValueCount > int.MaxValue)
            {
                throw new ArgumentException("can only handle valueCount < System.Int32.MaxValue; got " + dv.ValueCount);
            }
            valueCount = (int)dv.ValueCount;

            // TODO: we can make this more efficient if eg we can be
            // "involved" when IOrdinalMap is being created?  Ie see
            // each term/ord it's assigning as it goes...
            string lastDim = null;
            int startOrd = -1;
            BytesRef spare = new BytesRef();

            // TODO: this approach can work for full hierarchy?;
            // TaxoReader can't do this since ords are not in
            // "sorted order" ... but we should generalize this to
            // support arbitrary hierarchy:
            for (int ord = 0; ord < valueCount; ord++)
            {
                dv.LookupOrd(ord, spare);
                string[] components = FacetsConfig.StringToPath(spare.Utf8ToString());
                if (components.Length != 2)
                {
                    throw new ArgumentException("this class can only handle 2 level hierarchy (dim/value); got: " + Arrays.ToString(components) + " " + spare.Utf8ToString());
                }
                if (!components[0].Equals(lastDim, StringComparison.Ordinal))
                {
                    if (lastDim != null)
                    {
                        prefixToOrdRange[lastDim] = new OrdRange(startOrd, ord - 1);
                    }
                    startOrd = ord;
                    lastDim = components[0];
                }
            }

            if (lastDim != null)
            {
                prefixToOrdRange[lastDim] = new OrdRange(startOrd, valueCount - 1);
            }
        }

        /// <summary>
        /// Return top-level doc values.
        /// </summary>
        public override SortedSetDocValues GetDocValues() 
        {
            return topReader.GetSortedSetDocValues(field);
        }

        /// <summary>
        /// Returns mapping from prefix to <see cref="SortedSetDocValuesReaderState.OrdRange"/>.
        /// </summary>
        public override IDictionary<string, OrdRange> PrefixToOrdRange => prefixToOrdRange;

        /// <summary>
        /// Returns the <see cref="SortedSetDocValuesReaderState.OrdRange"/> for this dimension.
        /// </summary>
        public override OrdRange GetOrdRange(string dim)
        {
            prefixToOrdRange.TryGetValue(dim, out OrdRange result);
            return result;
        }

        /// <summary>
        /// Indexed field we are reading.
        /// </summary>
        public override string Field => field;

        public override IndexReader OrigReader => origReader;

        /// <summary>
        /// Number of unique labels.
        /// </summary>
        public override int Count => valueCount;
    }
}