using NUnit.Framework;
using System;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
using Assert = Lucene.Net.TestFramework.Assert;

#if !FEATURE_RANDOM_NEXTINT64_NEXTSINGLE
using RandomizedTesting.Generators; // for Random.NextInt64 extension method
#endif

namespace Lucene.Net.Util
{
    /*
     * 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.
     */

    [TestFixture]
    public class TestMergedIterator : LuceneTestCase
    {
        private const int REPEATS = 2;
        private const int VALS_TO_MERGE = 15000;

        [Test]
        public virtual void TestMergeEmpty()
        {
            IEnumerator<int> merged = new MergedEnumerator<int>();
            Assert.IsFalse(merged.MoveNext());

            merged = new MergedEnumerator<int>(new JCG.List<int>().GetEnumerator());
            Assert.IsFalse(merged.MoveNext());

            IEnumerator<int>[] itrs = new IEnumerator<int>[Random.Next(100)];
            for (int i = 0; i < itrs.Length; i++)
            {
                itrs[i] = new JCG.List<int>().GetEnumerator();
            }
            merged = new MergedEnumerator<int>(itrs);
            Assert.IsFalse(merged.MoveNext());
        }

        [Test]
        public virtual void TestNoDupsRemoveDups()
        {
            TestCase(1, 1, true);
        }

        [Test]
        public virtual void TestOffItrDupsRemoveDups()
        {
            TestCase(3, 1, true);
        }

        [Test]
        public virtual void TestOnItrDupsRemoveDups()
        {
            TestCase(1, 3, true);
        }

        [Test]
        public virtual void TestOnItrRandomDupsRemoveDups()
        {
            TestCase(1, -3, true);
        }

        [Test]
        public virtual void TestBothDupsRemoveDups()
        {
            TestCase(3, 3, true);
        }

        [Test]
        public virtual void TestBothDupsWithRandomDupsRemoveDups()
        {
            TestCase(3, -3, true);
        }

        [Test]
        public virtual void TestNoDupsKeepDups()
        {
            TestCase(1, 1, false);
        }

        [Test]
        public virtual void TestOffItrDupsKeepDups()
        {
            TestCase(3, 1, false);
        }

        [Test]
        public virtual void TestOnItrDupsKeepDups()
        {
            TestCase(1, 3, false);
        }

        [Test]
        public virtual void TestOnItrRandomDupsKeepDups()
        {
            TestCase(1, -3, false);
        }

        [Test]
        public virtual void TestBothDupsKeepDups()
        {
            TestCase(3, 3, false);
        }

        [Test]
        public virtual void TestBothDupsWithRandomDupsKeepDups()
        {
            TestCase(3, -3, false);
        }

        private void TestCase(int itrsWithVal, int specifiedValsOnItr, bool removeDups)
        {
            // Build a random number of lists
            IList<int> expected = new JCG.List<int>();
            Random random = new J2N.Randomizer(Random.NextInt64());
            int numLists = itrsWithVal + random.Next(1000 - itrsWithVal);
            IList<int>[] lists = new IList<int>[numLists];
            for (int i = 0; i < numLists; i++)
            {
                lists[i] = new JCG.List<int>();
            }
            int start = random.Next(1000000);
            int end = start + VALS_TO_MERGE / itrsWithVal / Math.Abs(specifiedValsOnItr);
            for (int i = start; i < end; i++)
            {
                int maxList = lists.Length;
                int maxValsOnItr = 0;
                int sumValsOnItr = 0;
                for (int itrWithVal = 0; itrWithVal < itrsWithVal; itrWithVal++)
                {
                    int list = random.Next(maxList);
                    int valsOnItr = specifiedValsOnItr < 0 ? (1 + random.Next(-specifiedValsOnItr)) : specifiedValsOnItr;
                    maxValsOnItr = Math.Max(maxValsOnItr, valsOnItr);
                    sumValsOnItr += valsOnItr;
                    for (int valOnItr = 0; valOnItr < valsOnItr; valOnItr++)
                    {
                        lists[list].Add(i);
                    }
                    maxList = maxList - 1;
                    ArrayUtil.Swap(lists, list, maxList);
                }
                int maxCount = removeDups ? maxValsOnItr : sumValsOnItr;
                for (int count = 0; count < maxCount; count++)
                {
                    expected.Add(i);
                }
            }
            // Now check that they get merged cleanly
            IEnumerator<int>[] itrs = new IEnumerator<int>[numLists];
            for (int i = 0; i < numLists; i++)
            {
                itrs[i] = lists[i].GetEnumerator();
            }
            try
            {
                MergedEnumerator<int> mergedItr = new MergedEnumerator<int>(removeDups, itrs);
                using IEnumerator<int> expectedItr = expected.GetEnumerator();
                while (expectedItr.MoveNext())
                {
                    Assert.IsTrue(mergedItr.MoveNext());
                    Assert.AreEqual(expectedItr.Current, mergedItr.Current);
                }
                Assert.IsFalse(mergedItr.MoveNext());
            }
            finally
            {
                IOUtils.Dispose(itrs);
            }
        }






        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestMergeEmptyIterator()
        {
            IEnumerator<int> merged = new MergedIterator<int>();
            Assert.IsFalse(merged.MoveNext());

            merged = new MergedIterator<int>(new JCG.List<int>().GetEnumerator());
            Assert.IsFalse(merged.MoveNext());

            IEnumerator<int>[] itrs = new IEnumerator<int>[Random.Next(100)];
            for (int i = 0; i < itrs.Length; i++)
            {
                itrs[i] = new JCG.List<int>().GetEnumerator();
            }
            merged = new MergedIterator<int>(itrs);
            Assert.IsFalse(merged.MoveNext());
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestNoDupsRemoveDupsIterator()
        {
            TestCaseIterator(1, 1, true);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestOffItrDupsRemoveDupsIterator()
        {
            TestCaseIterator(3, 1, true);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestOnItrDupsRemoveDupsIterator()
        {
            TestCaseIterator(1, 3, true);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestOnItrRandomDupsRemoveDupsIterator()
        {
            TestCaseIterator(1, -3, true);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestBothDupsRemoveDupsIterator()
        {
            TestCaseIterator(3, 3, true);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestBothDupsWithRandomDupsRemoveDupsIterator()
        {
            TestCaseIterator(3, -3, true);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestNoDupsKeepDupsIterator()
        {
            TestCaseIterator(1, 1, false);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestOffItrDupsKeepDupsIterator()
        {
            TestCaseIterator(3, 1, false);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestOnItrDupsKeepDupsIterator()
        {
            TestCaseIterator(1, 3, false);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestOnItrRandomDupsKeepDupsIterator()
        {
            TestCaseIterator(1, -3, false);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestBothDupsKeepDupsIterator()
        {
            TestCaseIterator(3, 3, false);
        }

        [Test]
        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        public virtual void TestBothDupsWithRandomDupsKeepDupsIterator()
        {
            TestCaseIterator(3, -3, false);
        }

        [Obsolete("This method will be removed in 4.8.0 release candidate.")]
        private void TestCaseIterator(int itrsWithVal, int specifiedValsOnItr, bool removeDups)
        {
            // Build a random number of lists
            IList<int> expected = new JCG.List<int>();
            Random random = new J2N.Randomizer(Random.NextInt64());
            int numLists = itrsWithVal + random.Next(1000 - itrsWithVal);
            IList<int>[] lists = new IList<int>[numLists];
            for (int i = 0; i < numLists; i++)
            {
                lists[i] = new JCG.List<int>();
            }
            int start = random.Next(1000000);
            int end = start + VALS_TO_MERGE / itrsWithVal / Math.Abs(specifiedValsOnItr);
            for (int i = start; i < end; i++)
            {
                int maxList = lists.Length;
                int maxValsOnItr = 0;
                int sumValsOnItr = 0;
                for (int itrWithVal = 0; itrWithVal < itrsWithVal; itrWithVal++)
                {
                    int list = random.Next(maxList);
                    int valsOnItr = specifiedValsOnItr < 0 ? (1 + random.Next(-specifiedValsOnItr)) : specifiedValsOnItr;
                    maxValsOnItr = Math.Max(maxValsOnItr, valsOnItr);
                    sumValsOnItr += valsOnItr;
                    for (int valOnItr = 0; valOnItr < valsOnItr; valOnItr++)
                    {
                        lists[list].Add(i);
                    }
                    maxList = maxList - 1;
                    ArrayUtil.Swap(lists, list, maxList);
                }
                int maxCount = removeDups ? maxValsOnItr : sumValsOnItr;
                for (int count = 0; count < maxCount; count++)
                {
                    expected.Add(i);
                }
            }
            // Now check that they get merged cleanly
            IEnumerator<int>[] itrs = new IEnumerator<int>[numLists];
            for (int i = 0; i < numLists; i++)
            {
                itrs[i] = lists[i].GetEnumerator();
            }

            MergedIterator<int> mergedItr = new MergedIterator<int>(removeDups, itrs);
            using IEnumerator<int> expectedItr = expected.GetEnumerator();
            while (expectedItr.MoveNext())
            {
                Assert.IsTrue(mergedItr.MoveNext());
                Assert.AreEqual(expectedItr.Current, mergedItr.Current);
            }
            Assert.IsFalse(mergedItr.MoveNext());
        }
    }
}
