/*
 * 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.solr.search;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import com.carrotsearch.randomizedtesting.annotations.Repeat;
import org.apache.lucene.geo.GeoTestUtil;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.FacetParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.metrics.MetricsMap;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.util.SpatialUtils;
import org.apache.solr.util.TestUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.distance.DistanceUtils;
import org.locationtech.spatial4j.shape.Point;

//Unlike TestSolr4Spatial, not parametrized / not generic.
public class TestSolr4Spatial2 extends SolrTestCaseJ4 {

  @BeforeClass
  public static void beforeClass() throws Exception {
    initCore("solrconfig-spatial.xml", "schema-spatial.xml");
  }

  @Override
  @Before
  public void setUp() throws Exception {
    super.setUp();
    clearIndex();
    RetrievalCombo.idCounter = 0;
  }

  @Test
  public void testQuadTreeRobustness() {
    assertU(adoc("id", "0", "oslocation", "244502.06 639062.07"));
    // old (pre 8.3.0) still works
    assertU(adoc("id", "0", "oslocationold", "244502.06 639062.07"));
  }

  @Test
  public void testBBox() throws Exception {
    String fieldName = random().nextBoolean() ? "bbox" : "bboxD_dynamic";
    assertU(adoc("id", "0"));//nothing
    assertU(adoc("id", "1", fieldName, "ENVELOPE(-10, 20, 15, 10)"));
    assertU(adoc("id", "2", fieldName, "ENVELOPE(22, 22, 10, 10)"));//pt
    assertU(commit());

    assertJQ(req("q", "{!field f="+fieldName+" filter=false score=overlapRatio " +
                "queryTargetProportion=0.25}" +
                "Intersects(ENVELOPE(10,25,12,10))",
            "fl", "*,score",
            "debug", "results"),//explain info
        "/response/docs/[0]/id=='2'",
        "/response/docs/[0]/score==0.75]",
        "/response/docs/[1]/id=='1'",
        "/response/docs/[1]/score==0.26666668]",
        "/response/docs/[2]/id=='0'",
        "/response/docs/[2]/score==0.0",

        "/response/docs/[1]/" + fieldName + "=='ENVELOPE(-10, 20, 15, 10)'"//stored value
        );

    //minSideLength with point query
    assertJQ(req("q", "{!field f="+fieldName+" filter=false score=overlapRatio " +
                "queryTargetProportion=0.5 minSideLength=1}" +
                "Intersects(ENVELOPE(0,0,12,12))",//pt
            "fl", "id,score",
            "debug", "results"),//explain info
        "/response/docs/[0]/id=='1'",
        "/response/docs/[0]/score==0.50333333]"//just over 0.5
    );

    //area2D
    assertJQ(req("q", "{!field f=" + fieldName + " filter=false score=area2D}" +
                "Intersects(ENVELOPE(0,0,12,12))",//pt
            "fl", "id,score",
            "debug", "results"),//explain info
        "/response/docs/[0]/id=='1'",
        "/response/docs/[0]/score==" + (30f * 5f) + "]"//150
    );
    //area (not 2D)
    assertJQ(req("q", "{!field f=" + fieldName + " filter=false score=area}" +
                "Intersects(ENVELOPE(0,0,12,12))",//pt
            "fl", "id,score",
            "debug", "results"),//explain info
        "/response/docs/[0]/id=='1'",
        "/response/docs/[0]/score==" + 146.39793f + "]"//a bit less than 150
    );
  }

  @Test
  public void testBadScoreParam() throws Exception {
    String fieldName = "bbox";
    assertQEx("expect friendly error message",
        "area2D",
        req("{!field f=" + fieldName + " filter=false score=bogus}Intersects(ENVELOPE(0,0,12,12))"),
        SolrException.ErrorCode.BAD_REQUEST);
  }

  @Test
  public void testRptWithGeometryField() throws Exception {
    //note: fails with "srpt_geohash" because it's not as precise
    final boolean testCache = true;
    final boolean testHeatmap = true;
    final boolean testPolygon = false; // default spatialContext doesn't handle this
    testRptWithGeometryField("srptgeom", testCache, testHeatmap, testPolygon);
  }

  @Test
  public void testRptWithGeometryGeo3dField() throws Exception {
    final boolean testCache = true;
    final boolean testHeatmap = true;
    final boolean testPolygon = true;
    testRptWithGeometryField("srptgeom_geo3d", testCache, testHeatmap, testPolygon);
  }

  @Test
  public void testRptWithGeometryGeo3dS2Field() throws Exception {
    final boolean testCache = false; // the test data is designed to provoke the cache for non-S2
    final boolean testHeatmap = false; // incompatible
    final boolean testPolygon = true;
    testRptWithGeometryField("srptgeom_s2_geo3d", testCache, testHeatmap, testPolygon);
  }

  @Test @Repeat(iterations = 10)
  public void testLLPDecodeIsStableAndPrecise() throws Exception {
    // test that LatLonPointSpatialField decode of docValue will round-trip (re-index then re-decode) to the same value
    @SuppressWarnings({"resource", "IOResourceOpenedButNotSafelyClosed"})
    SolrClient client = new EmbeddedSolrServer(h.getCore());// do NOT close it; it will close Solr

    final String fld = "llp_1_dv_dvasst";
    String ptOrig = GeoTestUtil.nextLatitude() + "," + GeoTestUtil.nextLongitude();
    assertU(adoc("id", "0", fld, ptOrig));
    assertU(commit());
    // retrieve it (probably less precision)
    String ptDecoded1 = (String) client.query(params("q", "id:0")).getResults().get(0).get(fld);
    // now write it back
    assertU(adoc("id", "0", fld, ptDecoded1));
    assertU(commit());
    // retrieve it; assert that it's the same as written
    String ptDecoded2 = (String) client.query(params("q", "id:0")).getResults().get(0).get(fld);
    assertEquals("orig:" + ptOrig, ptDecoded1, ptDecoded2);

    // test that the representation is pretty accurate
    final Point ptOrigObj = SpatialUtils.parsePoint(ptOrig, SpatialContext.GEO);
    final Point ptDecodedObj = SpatialUtils.parsePoint(ptDecoded1, SpatialContext.GEO);
    double deltaCentimeters = SpatialContext.GEO.calcDistance(ptOrigObj, ptDecodedObj) * DistanceUtils.DEG_TO_KM * 1000.0 * 100.0;
    //See javadocs of LatLonDocValuesField for these constants
    final Point absErrorPt = SpatialContext.GEO.getShapeFactory().pointXY(8.381903171539307E-8, 4.190951585769653E-8);
    double deltaCentimetersMax
        = SpatialContext.GEO.calcDistance(absErrorPt, 0,0) * DistanceUtils.DEG_TO_KM * 1000.0 * 100.0;
    assertEquals(1.0420371840922256, deltaCentimetersMax, 0.0);// just so that we see it in black & white in the test

    //max found by trial & error.  If we used 8 decimal places then we could get down to 1.04cm accuracy but then we
    // lose the ability to round-trip -- 40 would become 39.99999997  (ugh).
    assertTrue("deltaCm too high: " + deltaCentimeters, deltaCentimeters < 1.41);
    // Pt(x=105.29894270124083,y=-0.4371673760042398) to  Pt(x=105.2989428,y=-0.4371673) is 1.38568
  }

  @Test
  public void testLatLonRetrieval() throws Exception {
    final String ptHighPrecision =   "40.2996543270,-74.0824956673";
    final String ptLossOfPrecision = "40.2996544,-74.0824957"; // rounded version of the one above, losing precision

    // "_1" is single, "_N" is multiValued
    // "_dv" is docValues (otherwise not),  "_dvasst" is useDocValuesAsStored (otherwise not)
    // "_st" is stored" (otherwise not)

    // a random point using the number of decimal places we support for round-tripping.
    String randPointStr =
        new BigDecimal(GeoTestUtil.nextLatitude()).setScale(7, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString() +
        "," + new BigDecimal(GeoTestUtil.nextLongitude()).setScale(7, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();

    List<RetrievalCombo> combos = Arrays.asList(
        new RetrievalCombo("llp_1_dv_st", ptHighPrecision),
        new RetrievalCombo("llp_N_dv_st", Arrays.asList("-40,40", "-45,45")),
        new RetrievalCombo("llp_N_dv_st", Arrays.asList("-40,40")), // multiValued but 1 value

        new RetrievalCombo("llp_1_dv_dvasst", ptHighPrecision, ptLossOfPrecision),
        // this one comes back in a different order since it gets sorted low to high
        new RetrievalCombo("llp_N_dv_dvasst", Arrays.asList("-40,40", "-45,45"), Arrays.asList("-45,45", "-40,40")),
        new RetrievalCombo("llp_N_dv_dvasst", Arrays.asList(randPointStr)), // multiValued but 1 value
        // edge cases.  (note we sorted it as Lucene will internally)
        new RetrievalCombo("llp_N_dv_dvasst", Arrays.asList(
            "-90,180", "-90,-180",
            "0,0", "0,180", "0,-180",
            "90,0", "90,180", "90,-180")),

        new RetrievalCombo("llp_1_dv", ptHighPrecision, ptLossOfPrecision),
        new RetrievalCombo("llp_N_dv", Arrays.asList("-45,45", "-40,40"))

        );
    Collections.shuffle(combos, random());

    // add and commit
    for (RetrievalCombo combo : combos) {
      SolrInputDocument doc = new SolrInputDocument();
      doc.addField("id", "" + combo.id);
      for (String indexValue : combo.indexValues) {
        doc.addField(combo.fieldName, indexValue);
      }
      assertU(adoc(doc));
      if (TestUtils.rarely()) { // induce segments to potentially change internal behavior
        assertU(commit());
      }
    }
    assertU(commit());

    // create an assertJQ assertion string, once for fl=*, another for when the field is listed
    List<String> assertJQsFlListed = new ArrayList<>();
    List<String> assertJQsFlStar = new ArrayList<>();
    for (RetrievalCombo combo : combos) {
      String expect = "response/docs/[" + combo.id + "]/" + combo.fieldName + "==" + combo.expectReturnJSON;
      assertJQsFlListed.add(expect);
      if (combo.fieldName.endsWith("_dv")) {
        expect =  "response/docs/[" + combo.id + "]=={'id':'" + combo.id + "'}"; // only the id, nothing else
      }
      assertJQsFlStar.add(expect);
    }
    // check
    assertJQ(req("q","*:*", "sort", "id asc",
        "fl","*"),
        assertJQsFlStar.toArray(new String[0]));
    assertJQ(req("q","*:*", "sort", "id asc",
        "fl", "id," + combos.stream().map(c -> c.fieldName).collect(Collectors.joining(","))),
        assertJQsFlListed.toArray(new String[0]));
  }

  private static class RetrievalCombo {
    static int idCounter = 0;
    final int id = idCounter++;
    final String fieldName;
    final List<String> indexValues;
    final String expectReturnJSON; //or null if not expected in response

    RetrievalCombo(String fieldName, List<String> indexValues) { this(fieldName, indexValues, indexValues);}
    RetrievalCombo(String fieldName, List<String> indexValues, List<String> returnValues) {
      this.fieldName = fieldName;
      this.indexValues = indexValues;
      this.expectReturnJSON = returnValues.stream().collect(Collectors.joining("', '", "['", "']"));
    }
    RetrievalCombo(String fieldName, String indexValue) { this(fieldName, indexValue, indexValue); }
    RetrievalCombo(String fieldName, String indexValue, String returnValue) {
      this.fieldName = fieldName;
      this.indexValues = Collections.singletonList(indexValue);
      this.expectReturnJSON = "'" + returnValue + "'";
    }
  }

  private void testRptWithGeometryField(String fieldName, boolean testCache, boolean testHeatmap, boolean testPolygon) throws Exception {
    assertU(adoc("id", "0", fieldName, "ENVELOPE(-10, 20, 15, 10)"));
    assertU(adoc("id", "1", fieldName, "BUFFER(POINT(-10 15), 5)"));//circle at top-left corner
    assertU(optimize("maxSegments", "1"));// one segment.
    assertU(commit());

    // Search to the edge but not quite touching the indexed envelope of id=0.  It requires geom validation to
    //  eliminate id=0.  id=1 is found and doesn't require validation.  cache=false means no query cache.
    final SolrQueryRequest sameReq = req(
        "q", "{!cache=false field f=" + fieldName + "}Intersects(ENVELOPE(-20, -10.0001, 30, 15.0001))",
        "sort", "id asc");
    assertJQ(sameReq, "/response/numFound==1", "/response/docs/[0]/id=='1'");

    if (testCache) {
      // The tricky thing is verifying the cache works correctly...

      MetricsMap cacheMetrics = (MetricsMap) ((SolrMetricManager.GaugeWrapper)h.getCore().getCoreMetricManager().getRegistry().getMetrics().get("CACHE.searcher.perSegSpatialFieldCache_" + fieldName)).getGauge();
      assertEquals("1", cacheMetrics.getValue().get("cumulative_inserts").toString());
      assertEquals("0", cacheMetrics.getValue().get("cumulative_hits").toString());

      // Repeat the query earlier
      assertJQ(sameReq, "/response/numFound==1", "/response/docs/[0]/id=='1'");
      assertEquals("1", cacheMetrics.getValue().get("cumulative_hits").toString());

      assertEquals("1 segment",
          1, getSearcher().getRawReader().leaves().size());
      // Get key of first leaf reader -- this one contains the match for sure.
      Object leafKey1 = getFirstLeafReaderKey();

      // add new segment
      assertU(adoc("id", "3"));

      assertU(commit()); // sometimes merges (to one seg), sometimes won't

      // can still find the same document
      assertJQ(sameReq, "/response/numFound==1", "/response/docs/[0]/id=='1'");

      // When there are new segments, we accumulate another hit. This tests the cache was not blown away on commit.
      // (i.e. the cache instance is new but it should've been regenerated from the old one).
      // Checking equality for the first reader's cache key indicates whether the cache should still be valid.
      Object leafKey2 = getFirstLeafReaderKey();
      // get the current instance of metrics - the old one may not represent the current cache instance
      cacheMetrics = (MetricsMap) ((SolrMetricManager.GaugeWrapper)h.getCore().getCoreMetricManager().getRegistry().getMetrics().get("CACHE.searcher.perSegSpatialFieldCache_" + fieldName)).getGauge();
      assertEquals(leafKey1.equals(leafKey2) ? "2" : "1", cacheMetrics.getValue().get("cumulative_hits").toString());
    }

    if (testHeatmap) {
      // Now try to see if heatmaps work:
      assertJQ(req("q", "*:*", "facet", "true", FacetParams.FACET_HEATMAP, fieldName, "json.nl", "map"),
          "/facet_counts/facet_heatmaps/" + fieldName + "/minX==-180.0");
    }

    if (testPolygon) {
      String polygonWKT = "POLYGON((-11 12, -11 11, 10.5 12, -11 12))"; //right-angle triangle.  Counter-clockwise order
      assertJQ(req(
          "q", "{!cache=false field f=" + fieldName + "}Intersects(" + polygonWKT + ")",
          "sort", "id asc"), "/response/numFound==2");

      assertU(adoc("id", "9",
          fieldName, "POLYGON((" + // rectangle. Counter-clockwise order.
              "-118.080201721669 54.5864541583249," +
              "-118.080078279314 54.5864541583249," +
              "-118.080078279314 54.5865258517606," +
              "-118.080201721669 54.5865258517606," +
              "-118.080201721669 54.5864541583249))" ));
      assertU(commit());
      // should NOT match
      assertJQ(req("q", fieldName+":[55.0260828,-115.5085624 TO 55.02646,-115.507337]"),
          "/response/numFound==0");
    }
  }

  protected SolrIndexSearcher getSearcher() {
    // neat trick; needn't deal with the hassle RefCounted
    return (SolrIndexSearcher) h.getCore().getInfoRegistry().get("searcher");
  }


  protected Object getFirstLeafReaderKey() {
    return getSearcher().getRawReader().leaves().get(0).reader().getCoreCacheHelper().getKey();
  }

  @Test// SOLR-8541
  public void testConstantScoreQueryWithFilterPartOnly() {
    final String[] doc1 = {"id", "1", "srptgeom", "56.9485,24.0980"};
    assertU(adoc(doc1));
    assertU(commit());

    ModifiableSolrParams params = new ModifiableSolrParams();
    params.add("q", "{!geofilt sfield=\"srptgeom\" pt=\"56.9484,24.0981\" d=100}");
    params.add("hl", "true");
    params.add("hl.fl", "srptgeom");
    assertQ(req(params), "*[count(//doc)=1]", "count(//lst[@name='highlighting']/*)=1");
  }

  @Test // SOLR-14802
  public void testGeodistSortPossibleWithLatLonPointSpatialFieldOrSpatialRecursivePrefixTreeField() throws Exception {
    assertU(adoc("id", "1", "llp", "53.4721936,-2.24703", "srpt_quad", "53.425272,-2.322356"));
    assertU(commit());

    assertJQ(req(
            "q", "*:*",
            "fq", "{!geofilt}",
            "d", "50",
            "pt", "53.4721936,-2.24703",
            "sfield", "srpt_quad",
            "sort", "min(geodist(),geodist(llp,53.4721936,-2.24703)) asc"
            ),
            "/response/docs/[0]/id=='1'");

    assertJQ(req(
            "q", "*:*",
            "fq", "{!geofilt}",
            "d", "50",
            "pt", "53.4721936,-2.24703",
            "sfield", "srpt_quad",
            "sort", "min(geodist(),geodist(53.4721936,-2.24703,llp)) asc" // moved llp to the end
            ),
            "/response/docs/[0]/id=='1'");

    assertJQ(req(
            "q", "*:*",
            "fq", "{!geofilt}",
            "d", "50",
            "pt", "53.4721936,-2.24703",
            "sfield", "llp", // trying another field type
            "sort", "min(geodist(),geodist(53.4721936,-2.24703,srpt_quad)) asc"
            ),
            "/response/docs/[0]/id=='1'");
  }

  @Test // SOLR-14802
  public void testGeodistSortOrderCorrectWithLatLonPointSpatialFieldAndSpatialRecursivePrefixTreeField() throws Exception {
    assertU(adoc("id", "1", "llp", "53.4721936,-2.24703", "srpt_quad", "53.4721936,-2.24703"));
    assertU(adoc("id", "2", "llp", "53.425272,-2.322356", "srpt_quad", "55.4721936,-2.24703"));
    assertU(commit());

    assertJQ(req(
            "q", "*:*",
            "fq", "{!geofilt}",
            "d", "50",
            "pt", "53.431669,-2.318720",
            "sfield", "srpt_quad",
            "sort", "min(geodist(),geodist(llp,53.431669,-2.318720)) asc"
            ),
            "/response/docs/[0]/id=='2'");

    assertJQ(req(
            "q", "*:*",
            "fq", "{!geofilt}",
            "d", "50",
            "pt", "53.4721936,-2.24703",
            "sfield", "srpt_quad",
            "sort", "min(geodist(),geodist(53.4721936,-2.24703,llp)) asc"
            ),
            "/response/docs/[0]/id=='1'");

    assertJQ(req(
            "q", "*:*",
            "fq", "{!geofilt}",
            "d", "50",
            "pt", "55.4721936,-2.24703",
            "sfield", "srpt_quad",
            "sort", "min(geodist(),geodist(55.4721936,-2.24703,llp)) asc"
            ),
            "/response/docs/[0]/id=='2'");
  }
}
