/*
 * 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.carbondata.core.util;

import java.util.Arrays;

import org.apache.carbondata.core.metadata.datatype.DataTypes;
import org.apache.carbondata.core.metadata.encoder.Encoding;
import org.apache.carbondata.core.metadata.schema.table.column.CarbonDimension;
import org.apache.carbondata.core.metadata.schema.table.column.ColumnSchema;
import org.apache.carbondata.core.scan.expression.ColumnExpression;
import org.apache.carbondata.core.scan.expression.Expression;
import org.apache.carbondata.core.scan.expression.LiteralExpression;
import org.apache.carbondata.core.scan.expression.conditional.GreaterThanEqualToExpression;
import org.apache.carbondata.core.scan.expression.conditional.GreaterThanExpression;
import org.apache.carbondata.core.scan.expression.conditional.LessThanEqualToExpression;
import org.apache.carbondata.core.scan.expression.conditional.NotEqualsExpression;
import org.apache.carbondata.core.scan.expression.logical.AndExpression;
import org.apache.carbondata.core.scan.expression.logical.OrExpression;
import org.apache.carbondata.core.scan.expression.logical.RangeExpression;
import org.apache.carbondata.core.scan.expression.logical.TrueExpression;
import org.apache.carbondata.core.scan.filter.executer.RangeValueFilterExecutorImpl;
import org.apache.carbondata.core.scan.filter.intf.FilterOptimizer;
import org.apache.carbondata.core.scan.filter.optimizer.RangeFilterOptimizer;
import org.apache.carbondata.core.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo;

import mockit.Deencapsulation;
import mockit.MockUp;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/* Test Cases for Range Filter */
public class RangeFilterProcessorTest {

  public static DimColumnResolvedFilterInfo dimColumnResolvedFilterInfo =
      new DimColumnResolvedFilterInfo();

  @BeforeClass public static void setUp() throws Exception {
    ColumnSchema columnSchema = new ColumnSchema();
    columnSchema.setDataType(DataTypes.STRING);
    CarbonDimension carbonDimension = new CarbonDimension(columnSchema, 0, 0, 0);
    dimColumnResolvedFilterInfo.setDimension(carbonDimension);
  }

  public boolean checkBothTrees(Expression a, Expression b) {

    if (null == a && null == b) {
      return true;
    }

    if (null == a) return false;
    if (null == b) return false;

    if ((a != null) && (b != null)) {
      return ((a.getClass() == b.getClass()) && (
          (a.getChildren().size() == 0 && b.getChildren().size() == 0) || (
              a.getChildren().size() == 2 && b.getChildren().size() == 2 && checkBothTrees(
                  a.getChildren().get(0), b.getChildren().get(0)) && checkBothTrees(
                  a.getChildren().get(1), b.getChildren().get(1)))));
    }
    return false;
  }

  @Test public void createFilterTree() {

    Expression inputFilter;
    boolean result = false;
    ColumnExpression cola = new ColumnExpression("a", DataTypes.STRING);
    cola.setDimension(true);

    ColumnSchema empColumnSchema = new ColumnSchema();
    empColumnSchema.setColumnName("empNameCol");
    empColumnSchema.setColumnUniqueId("empNameCol");
    empColumnSchema.setDimensionColumn(true);
    empColumnSchema.setEncodingList(Arrays.asList(Encoding.DICTIONARY));
    empColumnSchema.setDataType(DataTypes.STRING);
    CarbonDimension empDimension = new CarbonDimension(empColumnSchema, 0, 0, 0);
    cola.setDimension(empDimension);

    Expression greaterThan =
        new GreaterThanEqualToExpression(cola, new LiteralExpression("11", DataTypes.STRING));

    ColumnExpression colb = new ColumnExpression("a", DataTypes.STRING);
    colb.setDimension(true);
    colb.setDimension(empDimension);
    Expression lessThan =
        new LessThanEqualToExpression(colb, new LiteralExpression("20", DataTypes.STRING));
    inputFilter = new AndExpression(greaterThan, lessThan);

    Expression output = new AndExpression(new RangeExpression(
        new GreaterThanEqualToExpression(new ColumnExpression("a", DataTypes.STRING),
            new LiteralExpression("11", DataTypes.STRING)),
        new LessThanEqualToExpression(new ColumnExpression("a", DataTypes.STRING),
            new LiteralExpression("20", DataTypes.STRING))), new TrueExpression(null));
    FilterOptimizer rangeFilterOptimizer =
        new RangeFilterOptimizer(inputFilter);
    rangeFilterOptimizer.optimizeFilter();
    result = checkBothTrees(inputFilter, output);
    Assert.assertTrue(result);

  }

  @Test public void createFilterTree_noChange() {

    // Build 2nd Tree no change a < 5 and a > 20

    Expression inputFilter;
    boolean result = false;
    ColumnExpression cola = new ColumnExpression("a", DataTypes.STRING);
    cola.setDimension(true);

    ColumnSchema empColumnSchema = new ColumnSchema();
    empColumnSchema.setColumnName("empNameCol");
    empColumnSchema.setColumnUniqueId("empNameCol");
    empColumnSchema.setDimensionColumn(true);
    empColumnSchema.setEncodingList(Arrays.asList(Encoding.DICTIONARY));
    empColumnSchema.setDataType(DataTypes.STRING);
    CarbonDimension empDimension = new CarbonDimension(empColumnSchema, 0, 0, 0);
    cola.setDimension(empDimension);

    Expression greaterThan =
        new GreaterThanEqualToExpression(cola, new LiteralExpression("20", DataTypes.STRING));

    ColumnExpression colb = new ColumnExpression("a", DataTypes.STRING);
    colb.setDimension(true);
    colb.setDimension(empDimension);
    Expression lessThan =
        new LessThanEqualToExpression(colb, new LiteralExpression("05", DataTypes.STRING));
    inputFilter = new AndExpression(greaterThan, lessThan);

    Expression output = new AndExpression(
        new GreaterThanEqualToExpression(new ColumnExpression("a", DataTypes.STRING),
            new LiteralExpression("20", DataTypes.STRING)),
        new LessThanEqualToExpression(new ColumnExpression("a", DataTypes.STRING),
            new LiteralExpression("05", DataTypes.STRING)));
    FilterOptimizer rangeFilterOptimizer =
        new RangeFilterOptimizer(inputFilter);
    rangeFilterOptimizer.optimizeFilter();
    result = checkBothTrees(inputFilter, output);
    // no change
    Assert.assertTrue(result);
  }

  @Test public void createFilterTree_flavor1() {

    // Build 3rd BTree a >= '11' and a > '12' and a <= '20' and a <= '15'

    Expression inputFilter;
    boolean result = false;

    ColumnSchema empColumnSchema = new ColumnSchema();
    empColumnSchema.setColumnName("a");
    empColumnSchema.setColumnUniqueId("a");
    empColumnSchema.setDimensionColumn(true);
    empColumnSchema.setEncodingList(Arrays.asList(Encoding.DICTIONARY));
    empColumnSchema.setDataType(DataTypes.STRING);
    CarbonDimension empDimension = new CarbonDimension(empColumnSchema, 0, 0, 0);

    ColumnExpression cola1 = new ColumnExpression("a", DataTypes.STRING);
    cola1.setDimension(true);
    cola1.setDimension(empDimension);

    ColumnExpression cola2 = new ColumnExpression("a", DataTypes.STRING);
    cola2.setDimension(true);
    cola2.setDimension(empDimension);

    ColumnExpression cola3 = new ColumnExpression("a", DataTypes.STRING);
    cola3.setDimension(true);
    cola3.setDimension(empDimension);

    ColumnExpression cola4 = new ColumnExpression("a", DataTypes.STRING);
    cola4.setDimension(true);
    cola4.setDimension(empDimension);

    Expression lessThan1 =
        new LessThanEqualToExpression(cola1, new LiteralExpression("15", DataTypes.STRING));
    Expression lessThan2 =
        new LessThanEqualToExpression(cola2, new LiteralExpression("20", DataTypes.STRING));
    Expression greaterThan1 =
        new GreaterThanExpression(cola3, new LiteralExpression("12", DataTypes.STRING));
    Expression greaterThan2 =
        new GreaterThanEqualToExpression(cola4, new LiteralExpression("11", DataTypes.STRING));

    Expression And1 = new AndExpression(new NotEqualsExpression(null, null), greaterThan2);
    Expression And2 = new AndExpression(And1, greaterThan1);
    Expression And3 = new AndExpression(And2, lessThan2);
    inputFilter = new AndExpression(And3, lessThan1);

    // Build The output

    ColumnExpression colb1 = new ColumnExpression("a", DataTypes.STRING);
    cola1.setDimension(true);
    cola1.setDimension(empDimension);

    ColumnExpression colb2 = new ColumnExpression("a", DataTypes.STRING);
    cola2.setDimension(true);
    cola2.setDimension(empDimension);

    Expression greaterThanb1 =
        new GreaterThanExpression(cola3, new LiteralExpression("12", DataTypes.STRING));

    Expression lessThanb1 =
        new LessThanEqualToExpression(cola1, new LiteralExpression("15", DataTypes.STRING));

    Expression Andb1 =
        new AndExpression(new NotEqualsExpression(null, null), new TrueExpression(null));

    Expression Andb2 = new AndExpression(Andb1, new RangeExpression(greaterThanb1, lessThanb1));
    Expression Andb3 = new AndExpression(Andb2, new TrueExpression(null));

    FilterOptimizer rangeFilterOptimizer =
        new RangeFilterOptimizer(inputFilter);
    rangeFilterOptimizer.optimizeFilter();
    result = checkBothTrees(inputFilter, new AndExpression(Andb3, new TrueExpression(null)));
    // no change
    Assert.assertTrue(result);
  }

  @Test public void createFilterTree_flavor2() {

    // Build 3rd BTree a >= '11' or a > '12' or a <= '20' or a <= '15'

    Expression inputFilter;
    boolean result = false;

    ColumnSchema empColumnSchema = new ColumnSchema();
    empColumnSchema.setColumnName("a");
    empColumnSchema.setColumnUniqueId("a");
    empColumnSchema.setDimensionColumn(true);
    empColumnSchema.setEncodingList(Arrays.asList(Encoding.DICTIONARY));
    empColumnSchema.setDataType(DataTypes.STRING);
    CarbonDimension empDimension = new CarbonDimension(empColumnSchema, 0, 0, 0);

    ColumnExpression cola1 = new ColumnExpression("a", DataTypes.STRING);
    cola1.setDimension(true);
    cola1.setDimension(empDimension);

    ColumnExpression cola2 = new ColumnExpression("a", DataTypes.STRING);
    cola2.setDimension(true);
    cola2.setDimension(empDimension);

    ColumnExpression cola3 = new ColumnExpression("a", DataTypes.STRING);
    cola3.setDimension(true);
    cola3.setDimension(empDimension);

    ColumnExpression cola4 = new ColumnExpression("a", DataTypes.STRING);
    cola4.setDimension(true);
    cola4.setDimension(empDimension);

    Expression lessThan1 =
        new LessThanEqualToExpression(cola1, new LiteralExpression("15", DataTypes.STRING));
    Expression lessThan2 =
        new LessThanEqualToExpression(cola2, new LiteralExpression("20", DataTypes.STRING));
    Expression greaterThan1 =
        new GreaterThanExpression(cola3, new LiteralExpression("12", DataTypes.STRING));
    Expression greaterThan2 =
        new GreaterThanEqualToExpression(cola4, new LiteralExpression("11", DataTypes.STRING));

    Expression Or1 = new OrExpression(new NotEqualsExpression(null, null), greaterThan2);
    Expression Or2 = new OrExpression(Or1, greaterThan1);
    Expression Or3 = new OrExpression(Or2, lessThan2);
    inputFilter = new OrExpression(Or3, lessThan1);

    // Build The output

    ColumnExpression colb1 = new ColumnExpression("a", DataTypes.STRING);
    cola1.setDimension(true);
    cola1.setDimension(empDimension);

    ColumnExpression colb2 = new ColumnExpression("a", DataTypes.STRING);
    cola2.setDimension(true);
    cola2.setDimension(empDimension);

    ColumnExpression colb3 = new ColumnExpression("a", DataTypes.STRING);
    cola3.setDimension(true);
    cola3.setDimension(empDimension);

    ColumnExpression colb4 = new ColumnExpression("a", DataTypes.STRING);
    cola4.setDimension(true);
    cola4.setDimension(empDimension);

    Expression lessThanb1 =
        new LessThanEqualToExpression(colb1, new LiteralExpression("15", DataTypes.STRING));
    Expression lessThanb2 =
        new LessThanEqualToExpression(colb2, new LiteralExpression("20", DataTypes.STRING));
    Expression greaterThanb1 =
        new GreaterThanExpression(colb3, new LiteralExpression("12", DataTypes.STRING));
    Expression greaterThanb2 =
        new GreaterThanEqualToExpression(colb4, new LiteralExpression("11", DataTypes.STRING));

    Expression Orb1 = new OrExpression(new NotEqualsExpression(null, null), greaterThanb2);
    Expression Orb2 = new OrExpression(Orb1, greaterThanb1);
    Expression Orb3 = new OrExpression(Orb2, lessThanb2);

    FilterOptimizer rangeFilterOptimizer =
        new RangeFilterOptimizer(inputFilter);
    rangeFilterOptimizer.optimizeFilter();
    result = checkBothTrees(inputFilter, new OrExpression(Orb3, lessThanb1));
    // no change
    Assert.assertTrue(result);
  }

  @Test public void checkIsScanRequired1() {
    byte[] BlockMin = { 1 };
    byte[] BlockMax = { 2 };
    boolean result;

    byte[][] filterMinMax = { { (byte) 10 }, { (byte) 20 } };

    RangeValueFilterExecutorImpl range = new MockUp<RangeValueFilterExecutorImpl>() {
    }.getMockInstance();
    Deencapsulation.setField(range, "isDimensionPresentInCurrentBlock", true);
    Deencapsulation.setField(range, "lessThanExp", true);
    Deencapsulation.setField(range, "greaterThanExp", true);
    Deencapsulation.setField(range, "dimColEvaluatorInfo", dimColumnResolvedFilterInfo);

    result = range.isScanRequired(BlockMin, BlockMax, filterMinMax, true);
    Assert.assertFalse(result);
  }

  @Test public void checkIsScanRequired1_1() {
    byte[] BlockMin = { 21 };
    byte[] BlockMax = { 22 };
    boolean result;

    byte[][] filterMinMax = { { (byte) 10 }, { (byte) 20 } };

    RangeValueFilterExecutorImpl range = new MockUp<RangeValueFilterExecutorImpl>() {
    }.getMockInstance();
    Deencapsulation.setField(range, "isDimensionPresentInCurrentBlock", true);
    Deencapsulation.setField(range, "lessThanExp", true);
    Deencapsulation.setField(range, "greaterThanExp", true);
    Deencapsulation.setField(range, "dimColEvaluatorInfo", dimColumnResolvedFilterInfo);
    result = range.isScanRequired(BlockMin, BlockMax, filterMinMax, true);
    Assert.assertFalse(result);
  }

  @Test public void checkIsScanRequired2() {
    byte[] BlockMin = { 12 };
    byte[] BlockMax = { 16 };
    boolean result;

    byte[][] filterMinMax = { { (byte) 10 }, { (byte) 20 } };

    RangeValueFilterExecutorImpl range = new MockUp<RangeValueFilterExecutorImpl>() {
    }.getMockInstance();
    Deencapsulation.setField(range, "isDimensionPresentInCurrentBlock", true);
    Deencapsulation.setField(range, "lessThanExp", true);
    Deencapsulation.setField(range, "greaterThanExp", true);
    Deencapsulation.setField(range, "dimColEvaluatorInfo", dimColumnResolvedFilterInfo);
    result = range.isScanRequired(BlockMin, BlockMax, filterMinMax, true);
    Assert.assertTrue(result);
  }

  @Test public void checkIsScanRequired3() {
    byte[] BlockMin = { 12 };
    byte[] BlockMax = { 16 };
    boolean result;
    boolean rangeCovered;

    byte[][] filterMinMax = { { (byte) 10 }, { (byte) 20 } };

    RangeValueFilterExecutorImpl range = new MockUp<RangeValueFilterExecutorImpl>() {
    }.getMockInstance();
    Deencapsulation.setField(range, "isDimensionPresentInCurrentBlock", true);
    Deencapsulation.setField(range, "lessThanExp", true);
    Deencapsulation.setField(range, "greaterThanExp", true);
    Deencapsulation.setField(range, "dimColEvaluatorInfo", dimColumnResolvedFilterInfo);

    result = range.isScanRequired(BlockMin, BlockMax, filterMinMax, true);
    rangeCovered = Deencapsulation.getField(range, "isRangeFullyCoverBlock");
    Assert.assertTrue(result);
    Assert.assertTrue(rangeCovered);
  }

  @Test public void checkIsScanRequired4() {
    byte[] BlockMin = { 12 };
    byte[] BlockMax = { 30 };
    boolean result;
    boolean startBlockMinIsDefaultStart;

    byte[][] filterMinMax = { { (byte) 10 }, { (byte) 20 } };

    RangeValueFilterExecutorImpl range = new MockUp<RangeValueFilterExecutorImpl>() {
    }.getMockInstance();
    Deencapsulation.setField(range, "isDimensionPresentInCurrentBlock", true);
    Deencapsulation.setField(range, "lessThanExp", true);
    Deencapsulation.setField(range, "greaterThanExp", true);
    Deencapsulation.setField(range, "dimColEvaluatorInfo", dimColumnResolvedFilterInfo);

    result = range.isScanRequired(BlockMin, BlockMax, filterMinMax, true);
    startBlockMinIsDefaultStart = Deencapsulation.getField(range, "startBlockMinIsDefaultStart");
    Assert.assertTrue(result);
    Assert.assertTrue(startBlockMinIsDefaultStart);
  }

  @Test public void checkIsScanRequired5() {
    byte[] BlockMin = { 10 };
    byte[] BlockMax = { 16 };
    boolean result;
    boolean endBlockMaxisDefaultEnd;

    byte[][] filterMinMax = { { (byte) 15 }, { (byte) 20 } };

    RangeValueFilterExecutorImpl range = new MockUp<RangeValueFilterExecutorImpl>() {
    }.getMockInstance();
    Deencapsulation.setField(range, "isDimensionPresentInCurrentBlock", true);
    Deencapsulation.setField(range, "lessThanExp", true);
    Deencapsulation.setField(range, "greaterThanExp", true);
    Deencapsulation.setField(range, "dimColEvaluatorInfo", dimColumnResolvedFilterInfo);

    result = range.isScanRequired(BlockMin, BlockMax, filterMinMax, true);
    endBlockMaxisDefaultEnd = Deencapsulation.getField(range, "endBlockMaxisDefaultEnd");
    Assert.assertTrue(result);
    Assert.assertTrue(endBlockMaxisDefaultEnd);
  }

  @AfterClass public static void testcleanUp() {
  }

}

