package org.apache.lucene.spatial.util;

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

import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.distance.DistanceCalculator;
import com.spatial4j.core.shape.Point;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * An implementation of the Lucene ValueSource that returns the spatial distance
 * between an input point and a document's points in
 * {@link ShapeFieldCacheProvider}. The shortest distance is returned if a
 * document has more than one point.
 *
 * @lucene.internal
 */
public class ShapeFieldCacheDistanceValueSource extends ValueSource {

  private final SpatialContext ctx;
  private final Point from;
  private final ShapeFieldCacheProvider<Point> provider;
  private final double multiplier;

  public ShapeFieldCacheDistanceValueSource(SpatialContext ctx,
      ShapeFieldCacheProvider<Point> provider, Point from, double multiplier) {
    this.ctx = ctx;
    this.from = from;
    this.provider = provider;
    this.multiplier = multiplier;
  }

  @Override
  public String description() {
    return getClass().getSimpleName()+"("+provider+", "+from+")";
  }

  @Override
  public FunctionValues getValues(Map context, final AtomicReaderContext readerContext) throws IOException {
    return new FunctionValues() {
      private final ShapeFieldCache<Point> cache =
          provider.getCache(readerContext.reader());
      private final Point from = ShapeFieldCacheDistanceValueSource.this.from;
      private final DistanceCalculator calculator = ctx.getDistCalc();
      private final double nullValue = (ctx.isGeo() ? 180 * multiplier : Double.MAX_VALUE);

      @Override
      public float floatVal(int doc) {
        return (float) doubleVal(doc);
      }

      @Override
      public double doubleVal(int doc) {

        List<Point> vals = cache.getShapes( doc );
        if( vals != null ) {
          double v = calculator.distance(from, vals.get(0));
          for( int i=1; i<vals.size(); i++ ) {
            v = Math.min(v, calculator.distance(from, vals.get(i)));
          }
          return v * multiplier;
        }
        return nullValue;
      }

      @Override
      public String toString(int doc) {
        return description() + "=" + floatVal(doc);
      }
    };
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    ShapeFieldCacheDistanceValueSource that = (ShapeFieldCacheDistanceValueSource) o;

    if (!ctx.equals(that.ctx)) return false;
    if (!from.equals(that.from)) return false;
    if (!provider.equals(that.provider)) return false;
    if (multiplier != that.multiplier) return false;

    return true;
  }

  @Override
  public int hashCode() {
    return from.hashCode();
  }
}
