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

import java.util.Arrays;
import java.util.List;

import org.apache.lucene.util.TimeUnits;
import org.apache.lucene.util.LuceneTestCase.Slow;
import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.IntervalFacet.Count;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.junit.BeforeClass;
import org.junit.Test;

import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;

@SuppressSSL(bugUrl="https://issues.apache.org/jira/browse/SOLR-9182 - causes OOM")
// See: https://issues.apache.org/jira/browse/SOLR-12028 Tests cannot remove files on Windows machines occasionally
@Slow
@TimeoutSuite(millis = 60 * TimeUnits.SECOND)
public class DistributedIntervalFacetingTest extends
    BaseDistributedSearchTestCase {

  @BeforeClass
  public static void beforeSuperClass() throws Exception {
    schemaString = "schema-distrib-interval-faceting.xml";
    configString = "solrconfig-basic.xml";
  }

  @Test
  public void test() throws Exception {
    del("*:*");
    commit();
    testRandom();
    del("*:*");
    commit();
    testSolrJ();
  }

  private void testSolrJ() throws Exception {
    indexr("id", "0", "test_i_dv", "0", "test_s_dv", "AAA");
    indexr("id", "1", "test_i_dv", "1", "test_s_dv", "BBB");
    indexr("id", "2", "test_i_dv", "2", "test_s_dv", "AAA");
    indexr("id", "3", "test_i_dv", "3", "test_s_dv", "CCC");
    commit();
    
    QueryResponse response = controlClient.query(new SolrQuery("*:*"));
    assertEquals(4, response.getResults().getNumFound());
    
    SolrQuery q = new SolrQuery("*:*");
    String[] intervals =  new String[]{"[0,1)","[1,2)", "[2,3)", "[3,*)"};
    q.addIntervalFacets("test_i_dv", intervals);
    response = controlClient.query(q);
    assertEquals(1, response.getIntervalFacets().size());
    assertEquals("test_i_dv", response.getIntervalFacets().get(0).getField());
    assertEquals(4, response.getIntervalFacets().get(0).getIntervals().size());
    for (int i = 0; i < response.getIntervalFacets().get(0).getIntervals().size(); i++) {
      Count count = response.getIntervalFacets().get(0).getIntervals().get(i);
      assertEquals(intervals[i], count.getKey());
      assertEquals(1, count.getCount());
    }
    
    q = new SolrQuery("*:*");
    q.addIntervalFacets("test_i_dv", intervals);
    q.addIntervalFacets("test_s_dv", new String[]{"{!key='AAA'}[AAA,AAA]", "{!key='BBB'}[BBB,BBB]", "{!key='CCC'}[CCC,CCC]"});
    response = controlClient.query(q);
    assertEquals(2, response.getIntervalFacets().size());
    
    int stringIntervalIndex = "test_s_dv".equals(response.getIntervalFacets().get(0).getField())?0:1;
        
    assertEquals("test_i_dv", response.getIntervalFacets().get(1-stringIntervalIndex).getField());
    assertEquals("test_s_dv", response.getIntervalFacets().get(stringIntervalIndex).getField());
    
    for (int i = 0; i < response.getIntervalFacets().get(1-stringIntervalIndex).getIntervals().size(); i++) {
      Count count = response.getIntervalFacets().get(1-stringIntervalIndex).getIntervals().get(i);
      assertEquals(intervals[i], count.getKey());
      assertEquals(1, count.getCount());
    }
    
    List<Count> stringIntervals = response.getIntervalFacets().get(stringIntervalIndex).getIntervals();
    assertEquals(3, stringIntervals.size());
    assertEquals("AAA", stringIntervals.get(0).getKey());
    assertEquals(2, stringIntervals.get(0).getCount());
    
    assertEquals("BBB", stringIntervals.get(1).getKey());
    assertEquals(1, stringIntervals.get(1).getCount());
    
    assertEquals("CCC", stringIntervals.get(2).getKey());
    assertEquals(1, stringIntervals.get(2).getCount());
  }

  private void testRandom() throws Exception {
    // All field values will be a number between 0 and cardinality
    int cardinality = 1000000;
    // Fields to use for interval faceting
    String[] fields = new String[]{"test_s_dv", "test_i_dv", "test_l_dv", "test_f_dv", "test_d_dv",
        "test_ss_dv", "test_is_dv", "test_fs_dv", "test_ls_dv", "test_ds_dv"};
    for (int i = 0; i < atLeast(500); i++) {
      if (random().nextInt(50) == 0) {
        //have some empty docs
        indexr("id", String.valueOf(i));
        continue;
      }

      if (random().nextInt(100) == 0 && i > 0) {
        //delete some docs
        del("id:" + String.valueOf(i - 1));
      }
      Object[] docFields = new Object[(random().nextInt(5)) * 10 + 12];
      docFields[0] = "id";
      docFields[1] = String.valueOf(i);
      docFields[2] = "test_s_dv";
      docFields[3] = String.valueOf(random().nextInt(cardinality));
      docFields[4] = "test_i_dv";
      docFields[5] = String.valueOf(random().nextInt(cardinality));
      docFields[6] = "test_l_dv";
      docFields[7] = String.valueOf(random().nextInt(cardinality));
      docFields[8] = "test_f_dv";
      docFields[9] = String.valueOf(random().nextFloat() * cardinality);
      docFields[10] = "test_d_dv";
      docFields[11] = String.valueOf(random().nextDouble() * cardinality);
      for (int j = 12; j < docFields.length; ) {
        docFields[j++] = "test_ss_dv";
        docFields[j++] = String.valueOf(random().nextInt(cardinality));
        docFields[j++] = "test_is_dv";
        docFields[j++] = String.valueOf(random().nextInt(cardinality));
        docFields[j++] = "test_ls_dv";
        docFields[j++] = String.valueOf(random().nextInt(cardinality));
        docFields[j++] = "test_fs_dv";
        docFields[j++] = String.valueOf(random().nextFloat() * cardinality);
        docFields[j++] = "test_ds_dv";
        docFields[j++] = String.valueOf(random().nextDouble() * cardinality);
      }
      indexr(docFields);
      if (random().nextInt(50) == 0) {
        commit();
      }
    }
    commit();

    handle.clear();
    handle.put("QTime", SKIPVAL);
    handle.put("timestamp", SKIPVAL);
    handle.put("maxScore", SKIPVAL);


    for (int i = 0; i < atLeast(100); i++) {
      doTestQuery(cardinality, fields);
    }

  }

  /**
   * Executes one query using interval faceting and compares with the same query using
   * facet query with the same range
   */
  private void doTestQuery(int cardinality, String[] fields) throws Exception {
    String[] startOptions = new String[]{"(", "["};
    String[] endOptions = new String[]{")", "]"};
    // the query should match some documents in most cases
    Integer[] qRange = getRandomRange(cardinality, "id");
    ModifiableSolrParams params = new ModifiableSolrParams();
    params.set("q", "id:[" + qRange[0] + " TO " + qRange[1] + "]");
    params.set("facet", "true");
    params.set("rows", "0");
    String field = fields[random().nextInt(fields.length)]; //choose from any of the fields
    if (random().nextBoolean()) {
      params.set("facet.interval", field);
    } else  {
      params.set("facet.interval", getFieldWithKey(field));
    }
    // number of intervals
    for (int i = 0; i < 1 + random().nextInt(20); i++) {
      Integer[] interval = getRandomRange(cardinality, field);
      String open = startOptions[interval[0] % 2];
      String close = endOptions[interval[1] % 2];
      params.add("f." + field + ".facet.interval.set", open + interval[0] + "," + interval[1] + close);
    }
    query(params);

  }

  private String getFieldWithKey(String field) {
    return "{!key='_some_key_for_" + field + "_" + random().nextInt() + "'}" + field;
  }

  /**
   * Returns a random range. It's guaranteed that the first
   * number will be lower than the second, and both of them
   * between 0 (inclusive) and <code>max</code> (exclusive).
   * If the fieldName is "test_s_dv" or "test_ss_dv" (the
   * two fields used for Strings), the comparison will be done
   * alphabetically
   */
  private Integer[] getRandomRange(int max, String fieldName) {
    Integer[] values = new Integer[2];
    values[0] = random().nextInt(max);
    values[1] = random().nextInt(max);
    if ("test_s_dv".equals(fieldName) || "test_ss_dv".equals(fieldName)) {
      Arrays.sort(values, (o1, o2) -> String.valueOf(o1).compareTo(String.valueOf(o2)));
    } else {
      Arrays.sort(values);
    }
    return values;
  }
}
