﻿using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Util;
using System;

namespace Lucene.Net.Join
{
    /*
     * 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>
    /// A field comparer that allows parent documents to be sorted by fields
    /// from the nested / child documents.
    /// 
    /// @lucene.experimental
    /// </summary>
    public abstract class ToParentBlockJoinFieldComparer : FieldComparer<object>
    {
        private readonly Filter _parentFilter;
        private readonly Filter _childFilter;
        private readonly int _spareSlot;

        private FieldComparer _wrappedComparer;
        private FixedBitSet _parentDocuments;
        private FixedBitSet _childDocuments;

        private ToParentBlockJoinFieldComparer(FieldComparer wrappedComparer, Filter parentFilter, Filter childFilter, int spareSlot)
        {
            _wrappedComparer = wrappedComparer;
            _parentFilter = parentFilter;
            _childFilter = childFilter;
            _spareSlot = spareSlot;
        }

        public override int Compare(int slot1, int slot2)
        {
            return _wrappedComparer.Compare(slot1, slot2);
        }

        public override void SetBottom(int slot)
        {
            _wrappedComparer.SetBottom(slot);
        }

        public override void SetTopValue(object value)
        {
            _wrappedComparer.SetTopValue(value);
        }
        
        public override FieldComparer SetNextReader(AtomicReaderContext context)
        {
            DocIdSet innerDocuments = _childFilter.GetDocIdSet(context, null);
            if (IsEmpty(innerDocuments))
            {
                _childDocuments = null;
            }
            else if (innerDocuments is FixedBitSet fixedBitSet)
            {
                _childDocuments = fixedBitSet;
            }
            else
            {
                DocIdSetIterator iterator = innerDocuments.GetIterator();
                _childDocuments = iterator != null ? ToFixedBitSet(iterator, context.AtomicReader.MaxDoc) : null;
            }
            DocIdSet rootDocuments = _parentFilter.GetDocIdSet(context, null);
            if (IsEmpty(rootDocuments))
            {
                _parentDocuments = null;
            }
            else if (rootDocuments is FixedBitSet fixedBitSet)
            {
                _parentDocuments = fixedBitSet;
            }
            else
            {
                DocIdSetIterator iterator = rootDocuments.GetIterator();
                _parentDocuments = iterator != null ? ToFixedBitSet(iterator, context.AtomicReader.MaxDoc) : null;
            }

            _wrappedComparer = _wrappedComparer.SetNextReader(context);
            return this;
        }

        private static bool IsEmpty(DocIdSet set)
        {
            return set == null;
        }
        
        private static FixedBitSet ToFixedBitSet(DocIdSetIterator iterator, int numBits)
        {
            var set = new FixedBitSet(numBits);
            int doc;
            while ((doc = iterator.NextDoc()) != DocIdSetIterator.NO_MORE_DOCS)
            {
                set.Set(doc);
            }
            return set;
        }

        // LUCENENET NOTE: This was value(int) in Lucene.
        public override IComparable this[int slot] => _wrappedComparer[slot];

        /// <summary>
        /// Concrete implementation of <see cref="ToParentBlockJoinSortField"/> to sorts the parent docs with the lowest values
        /// in the child / nested docs first.
        /// </summary>
        public sealed class Lowest : ToParentBlockJoinFieldComparer
        {
            /// <summary>
            /// Create <see cref="ToParentBlockJoinFieldComparer.Lowest"/>
            /// </summary>
            /// <param name="wrappedComparer">The <see cref="FieldComparer"/> on the child / nested level. </param>
            /// <param name="parentFilter"><see cref="Filter"/> (must produce <see cref="FixedBitSet"/> per-segment) that identifies the parent documents. </param>
            /// <param name="childFilter"><see cref="Filter"/> that defines which child / nested documents participates in sorting. </param>
            /// <param name="spareSlot">The extra slot inside the wrapped comparer that is used to compare which nested document
            ///                  inside the parent document scope is most competitive. </param>
            public Lowest(FieldComparer wrappedComparer, Filter parentFilter, Filter childFilter, int spareSlot) 
                : base(wrappedComparer, parentFilter, childFilter, spareSlot)
            {
            }
            
            public override int CompareBottom(int parentDoc)
            {
                if (parentDoc == 0 || _parentDocuments == null || _childDocuments == null)
                {
                    return 0;
                }

                // We need to copy the lowest value from all child docs into slot.
                int prevParentDoc = _parentDocuments.PrevSetBit(parentDoc - 1);
                int childDoc = _childDocuments.NextSetBit(prevParentDoc + 1);
                if (childDoc >= parentDoc || childDoc == -1)
                {
                    return 0;
                }

                // We only need to emit a single cmp value for any matching child doc
                int cmp = _wrappedComparer.CompareBottom(childDoc);
                if (cmp > 0)
                {
                    return cmp;
                }

                while (true)
                {
                    childDoc = _childDocuments.NextSetBit(childDoc + 1);
                    if (childDoc >= parentDoc || childDoc == -1)
                    {
                        return cmp;
                    }
                    int cmp1 = _wrappedComparer.CompareBottom(childDoc);
                    if (cmp1 > 0)
                    {
                        return cmp1;
                    }
                    if (cmp1 == 0)
                    {
                        cmp = 0;
                    }
                }
            }
            
            public override void Copy(int slot, int parentDoc)
            {
                if (parentDoc == 0 || _parentDocuments == null || _childDocuments == null)
                {
                    return;
                }

                // We need to copy the lowest value from all child docs into slot.
                int prevParentDoc = _parentDocuments.PrevSetBit(parentDoc - 1);
                int childDoc = _childDocuments.NextSetBit(prevParentDoc + 1);
                if (childDoc >= parentDoc || childDoc == -1)
                {
                    return;
                }
                _wrappedComparer.Copy(_spareSlot, childDoc);
                _wrappedComparer.Copy(slot, childDoc);

                while (true)
                {
                    childDoc = _childDocuments.NextSetBit(childDoc + 1);
                    if (childDoc >= parentDoc || childDoc == -1)
                    {
                        return;
                    }
                    _wrappedComparer.Copy(_spareSlot, childDoc);
                    if (_wrappedComparer.Compare(_spareSlot, slot) < 0)
                    {
                        _wrappedComparer.Copy(slot, childDoc);
                    }
                }
            }
            
            public override int CompareTop(int parentDoc)
            {
                if (parentDoc == 0 || _parentDocuments == null || _childDocuments == null)
                {
                    return 0;
                }

                // We need to copy the lowest value from all nested docs into slot.
                int prevParentDoc = _parentDocuments.PrevSetBit(parentDoc - 1);
                int childDoc = _childDocuments.NextSetBit(prevParentDoc + 1);
                if (childDoc >= parentDoc || childDoc == -1)
                {
                    return 0;
                }

                // We only need to emit a single cmp value for any matching child doc
                int cmp = _wrappedComparer.CompareBottom(childDoc);
                if (cmp > 0)
                {
                    return cmp;
                }

                while (true)
                {
                    childDoc = _childDocuments.NextSetBit(childDoc + 1);
                    if (childDoc >= parentDoc || childDoc == -1)
                    {
                        return cmp;
                    }
                    int cmp1 = _wrappedComparer.CompareTop(childDoc);
                    if (cmp1 > 0)
                    {
                        return cmp1;
                    }
                    if (cmp1 == 0)
                    {
                        cmp = 0;
                    }
                }
            }

        }

        /// <summary>
        /// Concrete implementation of <see cref="ToParentBlockJoinSortField"/> to sorts the parent docs with the highest values
        /// in the child / nested docs first.
        /// </summary>
        public sealed class Highest : ToParentBlockJoinFieldComparer
        {
            /// <summary>
            /// Create <see cref="ToParentBlockJoinFieldComparer.Highest"/>
            /// </summary>
            /// <param name="wrappedComparer">The <see cref="FieldComparer"/> on the child / nested level. </param>
            /// <param name="parentFilter"><see cref="Filter"/> (must produce <see cref="FixedBitSet"/> per-segment) that identifies the parent documents. </param>
            /// <param name="childFilter"><see cref="Filter"/> that defines which child / nested documents participates in sorting. </param>
            /// <param name="spareSlot">The extra slot inside the wrapped comparer that is used to compare which nested document
            ///                  inside the parent document scope is most competitive. </param>
            public Highest(FieldComparer wrappedComparer, Filter parentFilter, Filter childFilter, int spareSlot) 
                : base(wrappedComparer, parentFilter, childFilter, spareSlot)
            {
            }
            
            public override int CompareBottom(int parentDoc)
            {
                if (parentDoc == 0 || _parentDocuments == null || _childDocuments == null)
                {
                    return 0;
                }

                int prevParentDoc = _parentDocuments.PrevSetBit(parentDoc - 1);
                int childDoc = _childDocuments.NextSetBit(prevParentDoc + 1);
                if (childDoc >= parentDoc || childDoc == -1)
                {
                    return 0;
                }

                int cmp = _wrappedComparer.CompareBottom(childDoc);
                if (cmp < 0)
                {
                    return cmp;
                }

                while (true)
                {
                    childDoc = _childDocuments.NextSetBit(childDoc + 1);
                    if (childDoc >= parentDoc || childDoc == -1)
                    {
                        return cmp;
                    }
                    int cmp1 = _wrappedComparer.CompareBottom(childDoc);
                    if (cmp1 < 0)
                    {
                        return cmp1;
                    }
                    else
                    {
                        if (cmp1 == 0)
                        {
                            cmp = 0;
                        }
                    }
                }
            }
            
            public override void Copy(int slot, int parentDoc)
            {
                if (parentDoc == 0 || _parentDocuments == null || _childDocuments == null)
                {
                    return;
                }

                int prevParentDoc = _parentDocuments.PrevSetBit(parentDoc - 1);
                int childDoc = _childDocuments.NextSetBit(prevParentDoc + 1);
                if (childDoc >= parentDoc || childDoc == -1)
                {
                    return;
                }
                _wrappedComparer.Copy(_spareSlot, childDoc);
                _wrappedComparer.Copy(slot, childDoc);

                while (true)
                {
                    childDoc = _childDocuments.NextSetBit(childDoc + 1);
                    if (childDoc >= parentDoc || childDoc == -1)
                    {
                        return;
                    }
                    _wrappedComparer.Copy(_spareSlot, childDoc);
                    if (_wrappedComparer.Compare(_spareSlot, slot) > 0)
                    {
                        _wrappedComparer.Copy(slot, childDoc);
                    }
                }
            }
            
            public override int CompareTop(int parentDoc)
            {
                if (parentDoc == 0 || _parentDocuments == null || _childDocuments == null)
                {
                    return 0;
                }

                int prevParentDoc = _parentDocuments.PrevSetBit(parentDoc - 1);
                int childDoc = _childDocuments.NextSetBit(prevParentDoc + 1);
                if (childDoc >= parentDoc || childDoc == -1)
                {
                    return 0;
                }

                int cmp = _wrappedComparer.CompareBottom(childDoc);
                if (cmp < 0)
                {
                    return cmp;
                }

                while (true)
                {
                    childDoc = _childDocuments.NextSetBit(childDoc + 1);
                    if (childDoc >= parentDoc || childDoc == -1)
                    {
                        return cmp;
                    }
                    int cmp1 = _wrappedComparer.CompareTop(childDoc);
                    if (cmp1 < 0)
                    {
                        return cmp1;
                    }
                    if (cmp1 == 0)
                    {
                        cmp = 0;
                    }
                }
            }
        }
    }
}