/*
 * 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.analytics.function.mapping;

import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.Date;

import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.analytics.value.AnalyticsValueStream;
import org.apache.solr.analytics.value.DateValue;
import org.apache.solr.analytics.value.DoubleValue;
import org.apache.solr.analytics.value.FillableTestValue.TestDateValue;
import org.apache.solr.analytics.value.FillableTestValue.TestDateValueStream;
import org.apache.solr.analytics.value.FillableTestValue.TestDoubleValue;
import org.apache.solr.analytics.value.FillableTestValue.TestDoubleValueStream;
import org.apache.solr.analytics.value.FillableTestValue.TestFloatValue;
import org.apache.solr.analytics.value.FillableTestValue.TestFloatValueStream;
import org.apache.solr.analytics.value.FillableTestValue.TestIntValue;
import org.apache.solr.analytics.value.FillableTestValue.TestIntValueStream;
import org.apache.solr.analytics.value.FillableTestValue.TestLongValue;
import org.apache.solr.analytics.value.FillableTestValue.TestLongValueStream;
import org.apache.solr.analytics.value.FillableTestValue.TestStringValue;
import org.apache.solr.analytics.value.FillableTestValue.TestStringValueStream;
import org.apache.solr.analytics.value.FloatValue;
import org.apache.solr.analytics.value.IntValue;
import org.apache.solr.analytics.value.LongValue;
import org.apache.solr.analytics.value.StringValue;
import org.junit.Test;

public class TopFunctionTest extends SolrTestCaseJ4 {

  @Test
  public void multiValueIntTest() {
    TestIntValueStream val = new TestIntValueStream();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val});
    assertTrue(uncasted instanceof IntValue);
    IntValue func = (IntValue) uncasted;

    // Neither exists
    val.setValues();
    func.getInt();
    assertFalse(func.exists());

    // One exists
    val.setValues(30);
    assertEquals(30, func.getInt());
    assertTrue(func.exists());

    // Both exist
    val.setValues(30, 20, -10, 59);
    assertEquals(59, func.getInt());
    assertTrue(func.exists());
  }

  @Test
  public void multiValueLongTest() {
    TestLongValueStream val = new TestLongValueStream();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val});
    assertTrue(uncasted instanceof LongValue);
    LongValue func = (LongValue) uncasted;

    // Neither exists
    val.setValues();
    func.getLong();
    assertFalse(func.exists());

    // One exists
    val.setValues(30L);
    assertEquals(30L, func.getLong());
    assertTrue(func.exists());

    // Both exist
    val.setValues(30L, 20L, -10L, 59L);
    assertEquals(59L, func.getLong());
    assertTrue(func.exists());
  }

  @Test
  public void multiValueFloatTest() {
    TestFloatValueStream val = new TestFloatValueStream();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val});
    assertTrue(uncasted instanceof FloatValue);
    FloatValue func = (FloatValue) uncasted;

    // Neither exists
    val.setValues();
    func.getFloat();
    assertFalse(func.exists());

    // One exists
    val.setValues(30.0F);
    assertEquals(30.0F, func.getFloat(), .000001);
    assertTrue(func.exists());

    // Both exist
    val.setValues(30.5F, 20.01F, -10.49F, -10.48F);
    assertEquals(30.5F, func.getFloat(), .000001);
    assertTrue(func.exists());
  }

  @Test
  public void multiValueDoubleTest() {
    TestDoubleValueStream val = new TestDoubleValueStream();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val});
    assertTrue(uncasted instanceof DoubleValue);
    DoubleValue func = (DoubleValue) uncasted;

    // Neither exists
    val.setValues();
    func.getDouble();
    assertFalse(func.exists());

    // One exists
    val.setValues(30.0);
    assertEquals(30.0, func.getDouble(), .000001);
    assertTrue(func.exists());

    // Both exist
    val.setValues(30.5, 20.01, -10.49, -10.48);
    assertEquals(30.5, func.getDouble(), .000001);
    assertTrue(func.exists());
  }

  @Test
  public void multiValueDateTest() throws DateTimeParseException {
    TestDateValueStream val = new TestDateValueStream();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val});
    assertTrue(uncasted instanceof DateValue);
    DateValue func = (DateValue) uncasted;

    // Neither exists
    val.setValues();
    func.getDate();
    assertFalse(func.exists());

    // One exists
    val.setValues("1950-05-03T10:30:50Z");
    assertEquals(Date.from(Instant.parse("1950-05-03T10:30:50Z")), func.getDate());
    assertTrue(func.exists());

    // Both exist
    val.setValues("1950-05-03T10:30:50Z", "2200-01-01T10:00:50Z", "1800-12-31T11:30:50Z", "1930-05-020T10:45:50Z");
    assertEquals(Date.from(Instant.parse("2200-01-01T10:00:50Z")), func.getDate());
    assertTrue(func.exists());
  }

  @Test
  public void multiValueStringTest() {
    TestStringValueStream val = new TestStringValueStream();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val});
    assertTrue(uncasted instanceof StringValue);
    StringValue func = (StringValue) uncasted;

    // Neither exists
    val.setValues();
    func.getString();
    assertFalse(func.exists());

    // One exists
    val.setValues("abc");
    assertEquals("abc", func.getString());
    assertTrue(func.exists());

    // Both exist
    val.setValues("1abcdef", "abc", "def", "def1", "1abc");
    assertEquals("def1", func.getString());
    assertTrue(func.exists());
  }

  @Test
  public void multipleSingleValueIntTest() {
    TestIntValue val1 = new TestIntValue();
    TestIntValue val2 = new TestIntValue();
    TestIntValue val3 = new TestIntValue();
    TestIntValue val4 = new TestIntValue();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val1, val2, val3, val4});
    assertTrue(uncasted instanceof IntValue);
    IntValue func = (IntValue) uncasted;

    // None exist
    val1.setExists(false);
    val2.setExists(false);
    val3.setExists(false);
    val4.setExists(false);
    func.getInt();
    assertFalse(func.exists());

    // Some exist
    val1.setValue(1000).setExists(false);
    val2.setValue(30).setExists(true);
    val3.setValue(-1000).setExists(false);
    val4.setValue(12).setExists(true);
    assertEquals(30, func.getInt());
    assertTrue(func.exists());

    // All exist values, one value
    val1.setValue(45).setExists(true);
    val2.setValue(30).setExists(true);
    val3.setValue(-2).setExists(true);
    val4.setValue(12).setExists(true);
    assertEquals(45, func.getInt());
    assertTrue(func.exists());
  }

  @Test
  public void multipleSingleValueLongTest() {
    TestLongValue val1 = new TestLongValue();
    TestLongValue val2 = new TestLongValue();
    TestLongValue val3 = new TestLongValue();
    TestLongValue val4 = new TestLongValue();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val1, val2, val3, val4});
    assertTrue(uncasted instanceof LongValue);
    LongValue func = (LongValue) uncasted;

    // None exist
    val1.setExists(false);
    val2.setExists(false);
    val3.setExists(false);
    val4.setExists(false);
    func.getLong();
    assertFalse(func.exists());

    // Some exist
    val1.setValue(1000L).setExists(false);
    val2.setValue(30L).setExists(true);
    val3.setValue(-1000L).setExists(false);
    val4.setValue(12L).setExists(true);
    assertEquals(30L, func.getLong());
    assertTrue(func.exists());

    // All exist values, one value
    val1.setValue(45L).setExists(true);
    val2.setValue(30L).setExists(true);
    val3.setValue(-2L).setExists(true);
    val4.setValue(12L).setExists(true);
    assertEquals(45L, func.getLong());
    assertTrue(func.exists());
  }

  @Test
  public void multipleSingleValueFloatTest() {
    TestFloatValue val1 = new TestFloatValue();
    TestFloatValue val2 = new TestFloatValue();
    TestFloatValue val3 = new TestFloatValue();
    TestFloatValue val4 = new TestFloatValue();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val1, val2, val3, val4});
    assertTrue(uncasted instanceof FloatValue);
    FloatValue func = (FloatValue) uncasted;

    // None exist
    val1.setExists(false);
    val2.setExists(false);
    val3.setExists(false);
    val4.setExists(false);
    func.getFloat();
    assertFalse(func.exists());

    // Some exist
    val1.setValue(1000.1233F).setExists(false);
    val2.setValue(30.34F).setExists(true);
    val3.setValue(-1000.3241F).setExists(false);
    val4.setValue(12.123F).setExists(true);
    assertEquals(30.34F, func.getFloat(), .000001);
    assertTrue(func.exists());

    // All exist values, one value
    val1.setValue(45.43F).setExists(true);
    val2.setValue(30.231F).setExists(true);
    val3.setValue(-2.33F).setExists(true);
    val4.setValue(12.5F).setExists(true);
    assertEquals(45.43F, func.getFloat(), .000001);
    assertTrue(func.exists());
  }

  @Test
  public void multipleSingleValueDoubleTest() {
    TestDoubleValue val1 = new TestDoubleValue();
    TestDoubleValue val2 = new TestDoubleValue();
    TestDoubleValue val3 = new TestDoubleValue();
    TestDoubleValue val4 = new TestDoubleValue();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val1, val2, val3, val4});
    assertTrue(uncasted instanceof DoubleValue);
    DoubleValue func = (DoubleValue) uncasted;

    // None exist
    val1.setExists(false);
    val2.setExists(false);
    val3.setExists(false);
    val4.setExists(false);
    func.getDouble();
    assertFalse(func.exists());

    // Some exist
    val1.setValue(1000.1233).setExists(false);
    val2.setValue(30.34).setExists(true);
    val3.setValue(-1000.3241).setExists(false);
    val4.setValue(12.123).setExists(true);
    assertEquals(30.34, func.getDouble(), .000001);
    assertTrue(func.exists());

    // All exist values, one value
    val1.setValue(45.43).setExists(true);
    val2.setValue(30.231).setExists(true);
    val3.setValue(-2.33).setExists(true);
    val4.setValue(12.5).setExists(true);
    assertEquals(45.43, func.getDouble(), .000001);
    assertTrue(func.exists());
  }

  @Test
  public void multipleSingleValueDateTest() throws DateTimeParseException {
    TestDateValue val1 = new TestDateValue();
    TestDateValue val2 = new TestDateValue();
    TestDateValue val3 = new TestDateValue();
    TestDateValue val4 = new TestDateValue();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val1, val2, val3, val4});
    assertTrue(uncasted instanceof DateValue);
    DateValue func = (DateValue) uncasted;

    // None exist
    val1.setExists(false);
    val2.setExists(false);
    val3.setExists(false);
    val4.setExists(false);
    func.getDate();
    assertFalse(func.exists());

    // Some exist
    val1.setValue("9999-05-03T10:30:50Z").setExists(false);
    val2.setValue("1950-05-03T10:30:50Z").setExists(true);
    val3.setValue("0000-05-03T10:30:50Z").setExists(false);
    val4.setValue("1850-05-03T10:30:50Z").setExists(true);
    assertEquals(Date.from(Instant.parse("1950-05-03T10:30:50Z")), func.getDate());
    assertTrue(func.exists());

    // All exist values, one value
    val1.setValue("2200-05-03T10:30:50Z").setExists(true);
    val2.setValue("1950-05-03T10:30:50Z").setExists(true);
    val3.setValue("1700-05-03T10:30:50Z").setExists(true);
    val4.setValue("1850-05-03T10:30:50Z").setExists(true);
    assertEquals(Date.from(Instant.parse("2200-05-03T10:30:50Z")), func.getDate());
    assertTrue(func.exists());
  }

  @Test
  public void multipleStringValueDateTest() {
    TestStringValue val1 = new TestStringValue();
    TestStringValue val2 = new TestStringValue();
    TestStringValue val3 = new TestStringValue();
    TestStringValue val4 = new TestStringValue();

    AnalyticsValueStream uncasted = TopFunction.creatorFunction.apply(new AnalyticsValueStream[] {val1, val2, val3, val4});
    assertTrue(uncasted instanceof StringValue);
    StringValue func = (StringValue) uncasted;

    // None exist
    val1.setExists(false);
    val2.setExists(false);
    val3.setExists(false);
    val4.setExists(false);
    func.getString();
    assertFalse(func.exists());

    // Some exist
    val1.setValue("abc").setExists(true);
    val2.setValue("1111").setExists(false);
    val3.setValue("asdfads").setExists(true);
    val4.setValue("zzzzzzzz").setExists(false);
    assertEquals("asdfads", func.getString());
    assertTrue(func.exists());

    // All exist values, one value
    val1.setValue("abc").setExists(true);
    val2.setValue("abc1234").setExists(true);
    val3.setValue("fdgsfg1").setExists(true);
    val4.setValue("fdgsfg").setExists(true);
    assertEquals("fdgsfg1", func.getString());
    assertTrue(func.exists());
  }
}
