﻿using Lucene.Net.Documents;
using Lucene.Net.Documents.Extensions;
using Lucene.Net.Index;
using Lucene.Net.Search.Spell;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;

namespace Lucene.Net.Search.Suggest
{
    /*
     * 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>
    /// <para>
    /// Dictionary with terms, weights, payload (optional) and contexts (optional)
    /// information taken from stored/indexed fields in a Lucene index.
    /// </para>
    /// <b>NOTE:</b> 
    ///  <list type="bullet">
    ///    <item><description>
    ///      The term and (optionally) payload fields have to be
    ///      stored
    ///    </description></item>
    ///    <item><description>
    ///      The weight field can be stored or can be a <see cref="NumericDocValues"/>.
    ///      If the weight field is not defined, the value of the weight is <c>0</c>
    ///    </description></item>
    ///    <item><description>
    ///      if any of the term or (optionally) payload fields supplied
    ///      do not have a value for a document, then the document is 
    ///      skipped by the dictionary
    ///    </description></item>
    ///  </list>
    /// </summary>
    public class DocumentDictionary : IDictionary
    {
        /// <summary>
        /// <see cref="IndexReader"/> to load documents from </summary>
        protected readonly IndexReader m_reader;

        /// <summary>
        /// Field to read payload from </summary>
        protected readonly string m_payloadField;
        /// <summary>
        /// Field to read contexts from </summary>
        protected readonly string m_contextsField;
        private readonly string field;
        private readonly string weightField;

        /// <summary>
        /// Creates a new dictionary with the contents of the fields named <paramref name="field"/>
        /// for the terms and <paramref name="weightField"/> for the weights that will be used for
        /// the corresponding terms.
        /// </summary>
        public DocumentDictionary(IndexReader reader, string field, string weightField)
            : this(reader, field, weightField, null)
        {
        }

        /// <summary>
        /// Creates a new dictionary with the contents of the fields named <paramref name="field"/>
        /// for the terms, <paramref name="weightField"/> for the weights that will be used for the 
        /// the corresponding terms and <paramref name="payloadField"/> for the corresponding payloads
        /// for the entry.
        /// </summary>
        public DocumentDictionary(IndexReader reader, string field, string weightField, string payloadField)
            : this(reader, field, weightField, payloadField, null)
        {
        }

        /// <summary>
        /// Creates a new dictionary with the contents of the fields named <paramref name="field"/>
        /// for the terms, <paramref name="weightField"/> for the weights that will be used for the 
        /// the corresponding terms, <paramref name="payloadField"/> for the corresponding payloads
        /// for the entry and <paramref name="contextsField"/> for associated contexts.
        /// </summary>
        public DocumentDictionary(IndexReader reader, string field, string weightField, string payloadField, string contextsField)
        {
            this.m_reader = reader;
            this.field = field;
            this.weightField = weightField;
            this.m_payloadField = payloadField;
            this.m_contextsField = contextsField;
        }

        public virtual IInputEnumerator GetEntryEnumerator()
        {
            return new DocumentInputEnumerator(this, m_payloadField != null, m_contextsField != null);
        }

        /// <summary>
        /// Implements <see cref="IInputEnumerator"/> from stored fields. </summary>
        protected internal class DocumentInputEnumerator : IInputEnumerator
        {
            private readonly DocumentDictionary outerInstance;

            private readonly int docCount;
            private readonly ISet<string> relevantFields;
            private readonly bool hasPayloads;
            private readonly bool hasContexts;
            private readonly IBits liveDocs;
            private int currentDocId = -1;
            private long currentWeight;
            private BytesRef currentPayload;
            private ISet<BytesRef> currentContexts;
            private readonly NumericDocValues weightValues;
            private BytesRef current;

            /// <summary>
            /// Creates an iterator over term, weight and payload fields from the lucene
            /// index. Setting <paramref name="hasPayloads"/> to <c>false</c>, implies an enumerator
            /// over only term and weight.
            /// </summary>
            public DocumentInputEnumerator(DocumentDictionary documentDictionary, bool hasPayloads, bool hasContexts)
            {
                this.outerInstance = documentDictionary;
                this.hasPayloads = hasPayloads;
                this.hasContexts = hasContexts;
                docCount = documentDictionary.m_reader.MaxDoc - 1;
                weightValues = (documentDictionary.weightField != null) ? MultiDocValues.GetNumericValues(documentDictionary.m_reader, documentDictionary.weightField) : null;
                liveDocs = (documentDictionary.m_reader.Leaves.Count > 0) ? MultiFields.GetLiveDocs(documentDictionary.m_reader) : null;
                relevantFields = GetRelevantFields(new string[] { documentDictionary.field, documentDictionary.weightField, documentDictionary.m_payloadField, documentDictionary.m_contextsField });
            }

            public virtual long Weight => currentWeight;

            public virtual IComparer<BytesRef> Comparer => null;

            public BytesRef Current => current;

            public bool MoveNext()
            {
                while (currentDocId < docCount)
                {
                    currentDocId++;
                    if (liveDocs != null && !liveDocs.Get(currentDocId))
                    {
                        continue;
                    }

                    Document doc = outerInstance.m_reader.Document(currentDocId, relevantFields);

                    BytesRef tempPayload = null;
                    ISet<BytesRef> tempContexts = new JCG.HashSet<BytesRef>();

                    if (hasPayloads)
                    {
                        IIndexableField payload = doc.GetField(outerInstance.m_payloadField);
                        if (payload == null || (payload.GetBinaryValue() is null && payload.GetStringValue() is null))
                        {
                            continue;
                        }
                        tempPayload = payload.GetBinaryValue() ?? new BytesRef(payload.GetStringValue());
                    }

                    if (hasContexts)
                    {
                        IIndexableField[] contextFields = doc.GetFields(outerInstance.m_contextsField);
                        foreach (IIndexableField contextField in contextFields)
                        {
                            if (contextField.GetBinaryValue() is null && contextField.GetStringValue() is null)
                            {
                                continue;
                            }
                            else
                            {
                                tempContexts.Add(contextField.GetBinaryValue() ?? new BytesRef(contextField.GetStringValue()));
                            }
                        }
                    }

                    IIndexableField fieldVal = doc.GetField(outerInstance.field);
                    if (fieldVal == null || (fieldVal.GetBinaryValue() is null && fieldVal.GetStringValue() is null))
                    {
                        continue;
                    }
                    current = (fieldVal.GetStringValue() is null) ? fieldVal.GetBinaryValue() : new BytesRef(fieldVal.GetStringValue());

                    currentPayload = tempPayload;
                    currentContexts = tempContexts;
                    currentWeight = GetWeight(doc, currentDocId);

                    return true;
                }
                current = null;
                return false;
            }

            public virtual BytesRef Payload => currentPayload;

            public virtual bool HasPayloads => hasPayloads;

            /// <summary>
            /// Returns the value of the <see cref="Weight"/> property for the current document.
            /// Retrieves the value for the <see cref="Weight"/> property if its stored (using <paramref name="doc"/>)
            /// or if its indexed as <see cref="NumericDocValues"/> (using <paramref name="docId"/>) for the document.
            /// If no value is found, then the weight is 0.
            /// </summary>
            protected internal virtual long GetWeight(Document doc, int docId)
            {
                IIndexableField weight = doc.GetField(outerInstance.weightField);
                if (weight != null) // found weight as stored
                {
                    return weight.GetInt64ValueOrDefault();
                } // found weight as NumericDocValue
                else if (weightValues != null)
                {
                    return weightValues.Get(docId);
                } // fall back
                else
                {
                    return 0;
                }
            }

            private ISet<string> GetRelevantFields(params string[] fields)
            {
                var relevantFields = new JCG.HashSet<string>();
                foreach (string relevantField in fields)
                {
                    if (relevantField != null)
                    {
                        relevantFields.Add(relevantField);
                    }
                }
                return relevantFields;
            }

            public virtual ICollection<BytesRef> Contexts => hasContexts ? currentContexts : null;

            public virtual bool HasContexts => hasContexts;
        }
    }
}