﻿using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
using NUnit.Framework;
using Spatial4n.Core.Context;
using Spatial4n.Core.Distance;
using Spatial4n.Core.Shapes;
using System.Collections.Generic;
using System.Globalization;
using JCG = J2N.Collections.Generic;

namespace Lucene.Net.Spatial.Prefix
{
    /*
     * 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 TestRecursivePrefixTreeStrategy : StrategyTestCase
    {
        private int maxLength;

        //Tests should call this first.
        private void init(int maxLength)
        {
            this.maxLength = maxLength;
            this.ctx = SpatialContext.GEO;
            GeohashPrefixTree grid = new GeohashPrefixTree(ctx, maxLength);
            this.strategy = new RecursivePrefixTreeStrategy(grid, GetType().Name);
        }

        [Test]
        public virtual void TestFilterWithVariableScanLevel()
        {
            init(GeohashPrefixTree.MaxLevelsPossible);
            getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);

            //execute queries for each prefix grid scan level
            for (int i = 0; i <= maxLength; i++)
            {
                ((RecursivePrefixTreeStrategy)strategy).PrefixGridScanLevel = (i);
                executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
            }
        }

        [Test]
        public virtual void TestOneMeterPrecision()
        {
            init(GeohashPrefixTree.MaxLevelsPossible);
            GeohashPrefixTree grid = (GeohashPrefixTree)((RecursivePrefixTreeStrategy)strategy).Grid;
            //DWS: I know this to be true.  11 is needed for one meter
            double degrees = DistanceUtils.Dist2Degrees(0.001, DistanceUtils.EARTH_MEAN_RADIUS_KM);
            assertEquals(11, grid.GetLevelForDistance(degrees));
        }

        [Test]
        public virtual void TestPrecision()
        {
            init(GeohashPrefixTree.MaxLevelsPossible);

            Spatial4n.Core.Shapes.IPoint iPt = ctx.MakePoint(2.8028712999999925, 48.3708044);//lon, lat
            AddDocument(newDoc("iPt", iPt));
            Commit();

            Spatial4n.Core.Shapes.IPoint qPt = ctx.MakePoint(2.4632387000000335, 48.6003516);

            double KM2DEG = DistanceUtils.Dist2Degrees(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
            double DEG2KM = 1 / KM2DEG;

            double DIST = 35.75;//35.7499...
            assertEquals(DIST, ctx.DistCalc.Distance(iPt, qPt) * DEG2KM, 0.001);

            //distErrPct will affect the query shape precision. The indexed precision
            // was set to nearly zilch via init(GeohashPrefixTree.getMaxLevelsPossible());
            double distErrPct = 0.025; //the suggested default, by the way
            double distMult = 1 + distErrPct;

            assertTrue(35.74 * distMult >= DIST);
            checkHits(q(qPt, 35.74 * KM2DEG, distErrPct), 1, null);

            assertTrue(30 * distMult < DIST);
            checkHits(q(qPt, 30 * KM2DEG, distErrPct), 0, null);

            assertTrue(33 * distMult < DIST);
            checkHits(q(qPt, 33 * KM2DEG, distErrPct), 0, null);

            assertTrue(34 * distMult < DIST);
            checkHits(q(qPt, 34 * KM2DEG, distErrPct), 0, null);
        }

        private SpatialArgs q(Spatial4n.Core.Shapes.IPoint pt, double distDEG, double distErrPct)
        {
            IShape shape = ctx.MakeCircle(pt, distDEG);
            SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape);
            args.DistErrPct = (distErrPct);
            return args;
        }

        private void checkHits(SpatialArgs args, int assertNumFound, int[] assertIds)
        {
            SearchResults got = executeQuery(strategy.MakeQuery(args), 100);
            assertEquals("" + args, assertNumFound, got.numFound);
            if (assertIds != null)
            {
                ISet<int?> gotIds = new JCG.HashSet<int?>();
                foreach (SearchResult result in got.results)
                {
                    gotIds.add(int.Parse(result.document.Get("id"), CultureInfo.InvariantCulture));
                }
                foreach (int assertId in assertIds)
                {
                    assertTrue("has " + assertId, gotIds.contains(assertId));
                }
            }
        }
    }
}
