/*
 *
 * 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.
 *
*/

using Lucene.Net.Analysis;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Queries.Function;
using Lucene.Net.Queries.Function.ValueSources;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Support;
using Lucene.Net.Util;
using NUnit.Framework;

namespace Lucene.Net.Tests.Queries.Function
{
    /// <summary>
    /// Basic tests for <seealso cref="BoostedQuery"/>
    /// </summary>
    // TODO: more tests
    public class TestBoostedQuery : LuceneTestCase
    {
        internal static Directory dir;
        internal static IndexReader ir;
        internal static IndexSearcher @is;
        
        [SetUp]
        public override void SetUp()
        {
            base.SetUp();
            dir = NewDirectory();
            IndexWriterConfig iwConfig = NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random()));
            iwConfig.SetMergePolicy(NewLogMergePolicy());
            RandomIndexWriter iw = new RandomIndexWriter(Random(), dir, iwConfig);
            Document document = new Document();
            Field idField = new StringField("id", "", Field.Store.NO);
            document.Add(idField);
            iw.AddDocument(document);
            ir = iw.Reader;
            @is = NewSearcher(ir);
            iw.Dispose();
        }

        [TearDown]
        public override void TearDown()
        {
            @is = null;
            ir.Dispose();
            ir = null;
            dir.Dispose();
            dir = null;
            base.TearDown();
        }
        
        [Test]
        public virtual void TestBasic()
        {
            Query q = new MatchAllDocsQuery();
            TopDocs docs = @is.Search(q, 10);
            assertEquals(1, docs.TotalHits);
            float score = docs.ScoreDocs[0].Score;

            Query boostedQ = new BoostedQuery(q, new ConstValueSource(2.0f));
            AssertHits(boostedQ, new float[] { score * 2 });
        }


        private void AssertHits(Query q, float[] scores)
        {
            ScoreDoc[] expected = new ScoreDoc[scores.Length];
            int[] expectedDocs = new int[scores.Length];
            for (int i = 0; i < expected.Length; i++)
            {
                expectedDocs[i] = i;
                expected[i] = new ScoreDoc(i, scores[i]);
            }
            TopDocs docs = @is.Search(q, 10, new Sort(new SortField("id", SortFieldType.STRING)));
            CheckHits.DoCheckHits(Random(), q, "", @is, expectedDocs, Similarity);
            CheckHits.CheckHitsQuery(q, expected, docs.ScoreDocs, expectedDocs);
            CheckHits.CheckExplanations(q, "", @is);
        }
    }
}
