﻿using Lucene.Net.Documents;
using Lucene.Net.Queries.Function;
using Lucene.Net.Queries.Function.ValueSources;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
using Spatial4n.Core.Context;
using Spatial4n.Core.Shapes;
using System;

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

    /// <summary>
    /// The <see cref="SpatialStrategy"/> encapsulates an approach to indexing and searching based on shapes.
    /// <para/>
    /// Different implementations will support different features. A strategy should
    /// document these common elements:
    /// <list type="bullet">
    ///     <item><description>Can it index more than one shape per field?</description></item>
    ///     <item><description>What types of shapes can be indexed?</description></item>
    ///     <item><description>What types of query shapes can be used?</description></item>
    ///     <item><description>What types of query operations are supported? This might vary per shape.</description></item>
    ///     <item><description>Does it use the <see cref="FieldCache"/>, or some other type of cache?  When?</description></item>
    /// </list>
    /// If a strategy only supports certain shapes at index or query time, then in
    /// general it will throw an exception if given an incompatible one.  It will not
    /// be coerced into compatibility.
    /// <para/>
    /// Note that a SpatialStrategy is not involved with the Lucene stored field values of shapes, which is
    /// immaterial to indexing and search.
    /// <para/>
    /// Thread-safe.
    /// 
    /// @lucene.experimental
    /// </summary>
    public abstract class SpatialStrategy
    {
        protected readonly SpatialContext m_ctx;
        private readonly string fieldName;

        /// <summary>
        /// Constructs the spatial strategy with its mandatory arguments.
        /// </summary>
        protected SpatialStrategy(SpatialContext ctx, string fieldName)
        {
            this.m_ctx = ctx ?? throw new ArgumentNullException(nameof(ctx), "ctx is required");
            if (string.IsNullOrEmpty(fieldName))
                throw new ArgumentException("fieldName is required", nameof(fieldName));
            this.fieldName = fieldName;
        }

        public virtual SpatialContext SpatialContext => m_ctx;

        /// <summary>
        /// The name of the field or the prefix of them if there are multiple
        /// fields needed internally.
        /// </summary>
        /// <returns>Not null.</returns>
        public virtual string FieldName => fieldName;

        /// <summary>
        /// Returns the IndexableField(s) from the <paramref name="shape"/> that are to be
        /// added to the <see cref="Document"/>.  These fields
        /// are expected to be marked as indexed and not stored.
        /// <p/>
        /// Note: If you want to <i>store</i> the shape as a string for retrieval in search
        /// results, you could add it like this:
        /// <code>
        ///     document.Add(new StoredField(fieldName, ctx.ToString(shape)));
        /// </code>
        /// The particular string representation used doesn't matter to the Strategy since it
        /// doesn't use it.
        /// </summary>
        /// <param name="shape"></param>
        /// <returns>Not null nor will it have null elements.</returns>
        /// <exception cref="NotSupportedException">if given a shape incompatible with the strategy</exception>
        public abstract Field[] CreateIndexableFields(IShape shape);

        /// <summary>
        /// See <see cref="MakeDistanceValueSource(IPoint, double)"/> called with
        /// a multiplier of 1.0 (i.e. units of degrees).
        /// </summary>
        public virtual ValueSource MakeDistanceValueSource(IPoint queryPoint)
        {
            return MakeDistanceValueSource(queryPoint, 1.0);
        }

        /// <summary>
        /// Make a ValueSource returning the distance between the center of the
        /// indexed shape and <paramref name="queryPoint"/>.  If there are multiple indexed shapes
        /// then the closest one is chosen. The result is multiplied by <paramref name="multiplier"/>, which
        /// conveniently is used to get the desired units.
        /// </summary>
        public abstract ValueSource MakeDistanceValueSource(IPoint queryPoint, double multiplier);

        /// <summary>
        /// Make a Query based principally on <see cref="SpatialOperation"/>
        /// and <see cref="IShape"/> from the supplied <paramref name="args"/>.
        /// The default implementation is
        /// <code>return new ConstantScoreQuery(MakeFilter(args));</code>
        /// </summary>
        /// <exception cref="NotSupportedException">If the strategy does not support the shape in <paramref name="args"/>.</exception>
        /// <exception cref="UnsupportedSpatialOperation">If the strategy does not support the <see cref="SpatialOperation"/> in <paramref name="args"/>.</exception>
        public virtual ConstantScoreQuery MakeQuery(SpatialArgs args)
        {
            return new ConstantScoreQuery(MakeFilter(args));
        }

        /// <summary>
        /// Make a Filter based principally on <see cref="SpatialOperation"/>
        /// and <see cref="IShape"/> from the supplied <paramref name="args"/>.
        /// <para />
        /// If a subclasses implements
        /// <see cref="MakeQuery(SpatialArgs)"/>
        /// then this method could be simply:
        /// <code>return new QueryWrapperFilter(MakeQuery(args).Query);</code>
        /// </summary>
        /// <exception cref="NotSupportedException">If the strategy does not support the shape in <paramref name="args"/>.</exception>
        /// <exception cref="UnsupportedSpatialOperation">If the strategy does not support the <see cref="SpatialOperation"/> in <paramref name="args"/>.</exception>
        public abstract Filter MakeFilter(SpatialArgs args);

        /// <summary>
        /// Returns a ValueSource with values ranging from 1 to 0, depending inversely
        /// on the distance from <see cref="MakeDistanceValueSource(IPoint)"/>.
        /// The formula is <c>c / (d + c)</c> where 'd' is the distance and 'c' is
        /// one tenth the distance to the farthest edge from the center. Thus the
        /// scores will be 1 for indexed points at the center of the query shape and as
        /// low as ~0.1 at its furthest edges.
        /// </summary>
        public ValueSource MakeRecipDistanceValueSource(IShape queryShape)
        {
            IRectangle bbox = queryShape.BoundingBox;
            double diagonalDist = m_ctx.DistCalc.Distance(
                m_ctx.MakePoint(bbox.MinX, bbox.MinY), bbox.MaxX, bbox.MaxY);
            double distToEdge = diagonalDist * 0.5;
            float c = (float)distToEdge * 0.1f; //one tenth
            return new ReciprocalSingleFunction(MakeDistanceValueSource(queryShape.Center, 1.0), 1f, c, c);
        }

        public override string ToString()
        {
            return GetType().Name + " field:" + fieldName + " ctx=" + m_ctx;
        }
    }
}
