﻿using Lucene.Net.Randomized.Generators;
using Lucene.Net.Spatial.Prefix;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Serialized;
using Lucene.Net.Spatial.Vector;
using Lucene.Net.Support;
using NUnit.Framework;
using Spatial4n.Core.Context;
using Spatial4n.Core.Shapes;
using System;
using System.Collections.Generic;

namespace Lucene.Net.Spatial
{
    /*
     * 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 DistanceStrategyTest : StrategyTestCase
    {
        //@ParametersFactory
        public static IList<Object[]> Parameters()
        {
            List<Object[]> ctorArgs = new List<object[]>();

            SpatialContext ctx = SpatialContext.GEO;
            SpatialPrefixTree grid;
            SpatialStrategy strategy;

            grid = new QuadPrefixTree(ctx, 25);
            strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
            ctorArgs.Add(new Object[] { new Param(strategy) });

            grid = new GeohashPrefixTree(ctx, 12);
            strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
            ctorArgs.Add(new Object[] { new Param(strategy) });

            strategy = new PointVectorStrategy(ctx, "pointvector");
            ctorArgs.Add(new Object[] { new Param(strategy) });

            strategy = new SerializedDVStrategy(ctx, "serialized");
            ctorArgs.Add(new Object[] { new Param(strategy) });

            return ctorArgs;
        }

        // this is a hack for clover!
        public class Param
        {
            internal SpatialStrategy strategy;

            internal Param(SpatialStrategy strategy)
            {
                this.strategy = strategy;
            }


            public override String ToString()
            {
                return strategy.FieldName;
            }
        }

        //  private String fieldName;

        //public DistanceStrategyTest(Param param)
        //{
        //    SpatialStrategy strategy = param.strategy;
        //    this.ctx = strategy.SpatialContext;
        //    this.strategy = strategy;
        //}

        public override void SetUp()
        {
            SpatialStrategy strategy = ((Param)(RandomPicks.RandomFrom(Random, Parameters()))[0]).strategy;
            this.ctx = strategy.SpatialContext;
            this.strategy = strategy;
            base.SetUp();
        }


        protected override bool NeedsDocValues()
        {
            return (strategy is SerializedDVStrategy);
        }

        [Test]
        public virtual void TestDistanceOrder()
        {
            adoc("100", ctx.MakePoint(2, 1));
            adoc("101", ctx.MakePoint(-1, 4));
            adoc("103", (IShape)null);//test score for nothing
            adoc("999", ctx.MakePoint(2, 1));//test deleted
            Commit();
            DeleteDoc("999");
            Commit();
            //FYI distances are in docid order
            checkDistValueSource(ctx.MakePoint(4, 3), 2.8274937f, 5.0898066f, 180f);
            checkDistValueSource(ctx.MakePoint(0, 4), 3.6043684f, 0.9975641f, 180f);
        }

        [Test]
        public virtual void TestRecipScore()
        {
            IPoint p100 = ctx.MakePoint(2, 1);
            adoc("100", p100);
            IPoint p101 = ctx.MakePoint(-1, 4);
            adoc("101", p101);
            adoc("103", (IShape)null);//test score for nothing
            adoc("999", ctx.MakePoint(2, 1));//test deleted
            Commit();
            DeleteDoc("999");
            Commit();

            double dist = ctx.DistCalc.Distance(p100, p101);
            IShape queryShape = ctx.MakeCircle(2.01, 0.99, dist);
            CheckValueSource(strategy.MakeRecipDistanceValueSource(queryShape),
            new float[] { 1.00f, 0.10f, 0f }, 0.09f);
        }

        // @Override
        // protected Document newDoc(String id, Shape shape) {
        //   //called by adoc().  Make compatible with BBoxStrategy.
        //   if (shape != null && strategy instanceof BBoxStrategy)
        //     shape = ctx.makeRectangle(shape.getCenter(), shape.getCenter());
        //   return super.newDoc(id, shape);
        // }

        internal void checkDistValueSource(IPoint pt, params float[] distances)
        {
            float multiplier = (float)Random.NextDouble() * 100f;
            float[]
            dists2 = Arrays.CopyOf(distances, distances.Length);
            for (int i = 0; i < dists2.Length; i++)
            {
                dists2[i] *= multiplier;
            }
            CheckValueSource(strategy.MakeDistanceValueSource(pt, multiplier), dists2, 1.0e-3f);
        }

    }
}
