﻿using Lucene.Net.Index;
using Lucene.Net.Search;
using NUnit.Framework;
using System;
using Assert = Lucene.Net.TestFramework.Assert;
using Console = Lucene.Net.Util.SystemConsole;

namespace Lucene.Net.QueryParsers.Surround.Query
{
    /*
     * 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.
     */

    public class BooleanQueryTst
    {
        private string queryText;
        private readonly int[] expectedDocNrs;
        private SingleFieldTestDb dBase;
        private string fieldName;
        private BasicQueryFactory qf;
        private bool verbose = true;

        public BooleanQueryTst(
            string queryText,
            int[] expectedDocNrs,
            SingleFieldTestDb dBase,
            string fieldName,
            BasicQueryFactory qf)
        {
            this.queryText = queryText;
            this.expectedDocNrs = expectedDocNrs;
            this.dBase = dBase;
            this.fieldName = fieldName;
            this.qf = qf;
        }

        public virtual bool Verbose { set => this.verbose = value; }

        public virtual string QueryText => this.queryText;

        public virtual int[] ExpectedDocNrs => this.expectedDocNrs;

        internal class TestCollector : ICollector
        { // FIXME: use check hits from Lucene tests
            private int totalMatched;
            private bool[] encountered;
            private Scorer scorer = null;
            private int docBase = 0;
            private BooleanQueryTst parent;

            public TestCollector(BooleanQueryTst parent)
            {
                totalMatched = 0;
                encountered = new bool[parent.expectedDocNrs.Length];
                this.parent = parent;
            }

            public virtual void SetScorer(Scorer scorer)
            {
                this.scorer = scorer;
            }

            public virtual bool AcceptsDocsOutOfOrder => true;

            public virtual void SetNextReader(AtomicReaderContext context)
            {
                docBase = context.DocBase;
            }

            public virtual void Collect(int docNr)
            {
                float score = scorer.GetScore();
                docNr += docBase;
                /* System.out.println(docNr + " '" + dBase.getDocs()[docNr] + "': " + score); */
                Assert.True(score > 0.0, parent.QueryText + ": positive score");
                Assert.True(totalMatched < parent.ExpectedDocNrs.Length, parent.QueryText + ": too many hits");
                int i;
                for (i = 0; i < parent.expectedDocNrs.Length; i++)
                {
                    if ((!encountered[i]) && (parent.ExpectedDocNrs[i] == docNr))
                    {
                        encountered[i] = true;
                        break;
                    }
                }
                if (i == parent.ExpectedDocNrs.Length)
                {
                    Assert.True(false, parent.QueryText + ": doc nr for hit not expected: " + docNr);
                }
                totalMatched++;
            }

            public void CheckNrHits()
            {
                Assert.AreEqual(parent.ExpectedDocNrs.Length, totalMatched, parent.QueryText + ": nr of hits");
            }
        }

        public void DoTest()
        {

            if (verbose)
            {
                Console.WriteLine("");
                Console.WriteLine("Query: " + queryText);
            }

            SrndQuery lq = Parser.QueryParser.Parse(queryText);

            /* if (verbose) System.out.println("Srnd: " + lq.toString()); */

            Search.Query query = lq.MakeLuceneQueryField(fieldName, qf);
            /* if (verbose) System.out.println("Lucene: " + query.toString()); */

            TestCollector tc = new TestCollector(this);
            using (IndexReader reader = DirectoryReader.Open(dBase.Db))
            {
                IndexSearcher searcher = new IndexSearcher(reader);

                searcher.Search(query, tc);
            }
            tc.CheckNrHits();
        }
    }
}
