/*
 * 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.
 */
package org.apache.lucene.benchmark.byTask.feeds;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.lucene.benchmark.byTask.utils.Config;
import org.apache.lucene.queries.function.FunctionScoreQuery;
import org.apache.lucene.search.DoubleValuesSource;
import org.apache.lucene.search.Query;
import org.apache.lucene.spatial.SpatialStrategy;
import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.locationtech.spatial4j.shape.Shape;

/**
 * Reads spatial data from the body field docs from an internally created {@link LineDocSource}.
 * It's parsed by {@link org.locationtech.spatial4j.context.SpatialContext#readShapeFromWkt(String)}
 * (String)} and then further manipulated via a configurable {@link SpatialDocMaker.ShapeConverter}.
 * When using point data, it's likely you'll want to configure the shape converter so that the query
 * shapes actually cover a region. The queries are all created and cached in advance. This query
 * maker works in conjunction with {@link SpatialDocMaker}. See spatial.alg for a listing of
 * options, in particular the options starting with "query.".
 */
public class SpatialFileQueryMaker extends AbstractQueryMaker {
  protected SpatialStrategy strategy;
  protected double distErrPct; // NaN if not set
  protected SpatialOperation operation;
  protected boolean score;

  protected SpatialDocMaker.ShapeConverter shapeConverter;

  @Override
  public void setConfig(Config config) throws Exception {
    strategy = SpatialDocMaker.getSpatialStrategy(config.getRoundNumber());
    shapeConverter = SpatialDocMaker.makeShapeConverter(strategy, config, "query.spatial.");

    distErrPct = config.get("query.spatial.distErrPct", Double.NaN);
    operation = SpatialOperation.get(config.get("query.spatial.predicate", "Intersects"));
    score = config.get("query.spatial.score", false);

    super.setConfig(config); // call last, will call prepareQueries()
  }

  @Override
  protected Query[] prepareQueries() throws Exception {
    final int maxQueries = config.get("query.file.maxQueries", 1000);
    Config srcConfig = new Config(new Properties());
    srcConfig.set("docs.file", config.get("query.file", null));
    srcConfig.set("line.parser", config.get("query.file.line.parser", null));
    srcConfig.set("content.source.forever", "false");

    List<Query> queries = new ArrayList<>();
    LineDocSource src = new LineDocSource();
    try {
      src.setConfig(srcConfig);
      src.resetInputs();
      DocData docData = new DocData();
      for (int i = 0; i < maxQueries; i++) {
        docData = src.getNextDocData(docData);
        Shape shape =
            SpatialDocMaker.makeShapeFromString(strategy, docData.getName(), docData.getBody());
        if (shape != null) {
          shape = shapeConverter.convert(shape);
          queries.add(makeQueryFromShape(shape));
        } else {
          i--; // skip
        }
      }
    } catch (NoMoreDataException e) {
      // all-done
    } finally {
      src.close();
    }
    return queries.toArray(new Query[queries.size()]);
  }

  protected Query makeQueryFromShape(Shape shape) {
    SpatialArgs args = new SpatialArgs(operation, shape);
    if (!Double.isNaN(distErrPct)) args.setDistErrPct(distErrPct);

    Query filterQuery = strategy.makeQuery(args);
    if (score) {
      // wrap with distance computing query
      DoubleValuesSource valueSource = strategy.makeDistanceValueSource(shape.getCenter());
      return new FunctionScoreQuery(filterQuery, valueSource);
    } else {
      return filterQuery; // assume constant scoring
    }
  }
}
