/*
 * 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.drill.exec.fn.interp;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import org.apache.drill.PlanTestBase;
import org.apache.drill.categories.SqlTest;
import org.apache.drill.exec.planner.physical.PlannerSettings;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.io.File;
import java.io.PrintWriter;
import java.util.List;

@Category(SqlTest.class)
public class TestConstantFolding extends PlanTestBase {

  public static class SmallFileCreator {

    private final File folder;
    private static final List<String> values = Lists.newArrayList("1","2","3");
    private static final String jsonRecord =  "{\"col1\" : 1,\"col2\" : 2, \"col3\" : 3}";
    private String record;

    public SmallFileCreator(File folder) {
      this.folder = folder;
      this.record = null;
    }

    public SmallFileCreator setRecord(String record) {
      this.record = record;
      return this;
    }

    public void createFiles(int smallFileLines, int bigFileLines, String extension, String delimiter) throws Exception{
      if (record == null) {
        if (extension.equals("csv") || extension.equals("tsv")) {
          record = Joiner.on(delimiter).join(values);
        } else if (extension.equals("json") ){
          record = jsonRecord;
        } else {
          throw new UnsupportedOperationException(
              String.format("Extension %s not supported by %s",
                  extension, SmallFileCreator.class.getSimpleName()));
        }
      }
      PrintWriter out;
      for (String fileAndFolderName : new String[]{"bigfile", "BIGFILE_2"}) {
        File bigFolder = new File(folder, fileAndFolderName);
        bigFolder.mkdirs();
        File bigFile = new File (bigFolder, fileAndFolderName + "." + extension);
        out = new PrintWriter(bigFile);
        for (int i = 0; i < bigFileLines; i++ ) {
          out.println(record);
        }
        out.close();
      }

      for (String fileAndFolderName : new String[]{"smallfile", "SMALLFILE_2"}) {
        File smallFolder = new File(folder, fileAndFolderName);
        smallFolder.mkdirs();
        File smallFile = new File (smallFolder, fileAndFolderName + "." + extension);
        out = new PrintWriter(smallFile);
        for (int i = 0; i < smallFileLines; i++ ) {
          out.println(record);
        }
        out.close();
      }
    }

    public void createFiles(int smallFileLines, int bigFileLines, String extension) throws Exception{
      String delimiter;
      if (extension.equals("json")) {
        delimiter = null;
      } else if (extension.equals("csv")) {
        delimiter = ",";
      } else if (extension.equals("tsv")) {
        delimiter = "\t";
      } else {
        throw new UnsupportedOperationException("Extension not recognized, please explicitly provide a delimiter.");
      }
      createFiles(smallFileLines, bigFileLines, extension, delimiter);
    }

    public void createFiles(int smallFileLines, int bigFileLines) throws Exception{
      createFiles(smallFileLines, bigFileLines, "csv", ",");
    }

  }

  @Test
  public void testConstantFolding_allTypes() throws Exception {
    mockUsDateFormatSymbols();

    try {
      test("alter session set `store.json.all_text_mode` = true;");
      test(String.format("alter session set `%s` = true", PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY));

      String query2 = "SELECT *  " +
          "FROM   cp.`parquet/alltypes.json`  " +
          "WHERE  12 = extract(day from (to_timestamp('2014-02-12 03:18:31:07 AM', 'YYYY-MM-dd HH:mm:ss:SS a'))) " +
          "AND    cast( `int_col` AS             int) = castint('1')  " +
          "AND    cast( `bigint_col` AS          bigint) = castbigint('100000000000')  " +
          "AND    cast( `decimal9_col` AS        decimal(9, 4)) = 1.0 + 0.0  " +
          "AND    cast( `decimal18_col` AS       decimal(18,9)) = 123456789.000000000 + 0.0  " +
          "AND    cast( `decimal28sparse_col` AS decimal(28, 14)) = 123456789.000000000 + 0.0 " +
          "AND    cast( `decimal38sparse_col` AS decimal(38, 19)) = 123456789.000000000 + 0.0 " +
          "AND    cast( `date_col` AS            date) = cast('1995-01-01' as date)  " +
          "AND    cast( `date_col` AS            date) = castdate('1995-01-01')  " +
          "AND    cast( `date_col` AS            date) = DATE '1995-01-01'  " +
          "AND    cast( `timestamp_col` AS timestamp) = casttimestamp('1995-01-01 01:00:10.000')  " +
          "AND    cast( `float4_col` AS float) = castfloat4('1')  " +
          "AND    cast( `float8_col` AS DOUBLE) = castfloat8('1')  " +
          "AND    cast( `varbinary_col` AS varbinary(65000)) = castvarbinary('qwerty', 0)  " +
          "AND    cast( `intervalyear_col` AS interval year) = castintervalyear('P1Y')  " +
          "AND    cast( `intervalday_col` AS interval day) = castintervalday('P1D')" +
          "AND    cast( `bit_col` AS       boolean) = castbit('false')  " +
          "AND    `varchar_col` = concat('qwe','rty')  " +
          "AND    cast( `time_col` AS            time) = casttime('01:00:00')";


      testBuilder()
          .sqlQuery(query2)
          .ordered()
          .baselineColumns("TINYINT_col", "SMALLINT_col", "INT_col", "FLOAT4_col",
              "TIME_col", "DECIMAL9_col", "BIGINT_col", "UINT8_col", "FLOAT8_col",
              "DATE_col", "TIMESTAMP_col", "DECIMAL18_col", "INTERVALYEAR_col",
              "INTERVALDAY_col", "INTERVAL_col", "DECIMAL38SPARSE_col",
              "DECIMAL28SPARSE_col", "VARBINARY_col", "VARCHAR_col",
              "VAR16CHAR_col", "BIT_col")
          // the file is being read in all_text_mode to preserve exact values (as all numbers with decimal points are read
          // as double in the JsonReader), so the baseline values here are all specified as strings
          .baselineValues(
              "1", "1", "1", "1", "01:00:00", "1.0", "100000000000", "1", "1", "1995-01-01", "1995-01-01 01:00:10.000",
              "123456789.000000000", "P1Y", "P1D", "P1Y1M1DT1H1M", "123456789.000000000",
              "123456789.000000000", "qwerty", "qwerty","qwerty", "false")
          .go();
    } finally {
      test("alter session set `store.json.all_text_mode` = false;");
      test(String.format("alter session set `%s` = false", PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY));
    }
  }

  @Ignore("DRILL-2553")
  @Test
  public void testConstExprFolding_withPartitionPrune_verySmallFiles() throws Exception {
    new SmallFileCreator(dirTestWatcher.getRootDir()).createFiles(1, 8);
    testPlanOneExpectedPatternOneExcluded(
        "select * from dfs.`*/*.csv` where dir0 = concat('small','file')",
        "smallfile",
        "bigfile");
  }

  @Test
  public void testConstExprFolding_withPartitionPrune() throws Exception {
    new SmallFileCreator(dirTestWatcher.getRootDir()).createFiles(1, 1000);
    testPlanOneExpectedPatternOneExcluded(
        "select * from dfs.`*/*.csv` where dir0 = concat('small','file')",
        "smallfile",
        "bigfile");
  }

  @Test
  public void testConstExprFolding_nonDirFilter() throws Exception {
    testPlanOneExpectedPatternOneExcluded(
        "select * from cp.`functions/interp/test_input.csv` where columns[0] = 2+2",
        "Filter\\(condition=\\[=\\(ITEM\\(\\$[0-9]+, 0\\), 4\\)",
        "Filter\\(condition=\\[=\\(ITEM\\(\\$[0-9]+, 0\\), \\+\\(2, 2\\)\\)");
  }

  @Test
  public void testConstantFoldingDisableOption() throws Exception {
    try {
      test("alter session set `planner.enable_constant_folding` = false");
      testPlanOneExpectedPatternOneExcluded(
          "select * from cp.`functions/interp/test_input.csv` where columns[0] = 2+2",
          "Filter\\(condition=\\[=\\(ITEM\\(\\$[0-9]+, 0\\), \\+\\(2, 2\\)\\)",
          "Filter\\(condition=\\[=\\(ITEM\\(\\$[0-9]+, 0\\), 4\\)");
    } finally {
      test("alter session set `planner.enable_constant_folding` = true");
    }
  }

  @Test
  public void testConstExprFolding_moreComplicatedNonDirFilter() throws Exception {
    testPlanOneExpectedPatternOneExcluded(
        "select * from cp.`functions/interp/test_input.csv` where columns[1] = ABS((6-18)/(2*3))",
        "Filter\\(condition=\\[=\\(ITEM\\(\\$[0-9]+, 1\\), 2\\)",
        "Filter\\(condition=\\[=\\(ITEM\\(\\$[0-9]+, 1\\), ABS\\(/\\(-\\(6, 18\\), \\*\\(2, 3\\)\\)\\)\\)");
  }

  @Test
  public void testConstExprFolding_dontFoldRandom() throws Exception {
    testPlanOneExpectedPatternOneExcluded(
        "select * from cp.`functions/interp/test_input.csv` where columns[0] = random()",
        "Filter\\(condition=\\[=\\(ITEM\\(\\$[0-9]+, 0\\), RANDOM\\(\\)",
        "Filter\\(condition=\\[=\\(ITEM\\(\\$[0-9]+, 0\\), [0-9\\.]+");
  }

  @Test
  public void testConstExprFolding_ToLimit0() throws Exception {
    testPlanOneExpectedPatternOneExcluded(
        "select * from cp.`functions/interp/test_input.csv` where 1=0",
        "Limit\\(offset=\\[0\\], fetch=\\[0\\]\\)",
        "Filter\\(condition=\\[=\\(1, 0\\)\\]\\)");
  }

  // Despite a comment indicating that the plan generated by the ReduceExpressionRule
  // should be set to be always preferable to the input rel, I cannot get it to
  // produce a plan with the reduced result. I can trace through where the rule is fired
  // and I can see that the expression is being evaluated and the constant is being
  // added to a project, but this is not part of the final plan selected. May
  // need to open a calcite bug.
  // Tried to disable the calc and filter rules, only leave the project one, didn't help.
  @Ignore("DRILL-2218")
  @Test
  public void testConstExprFolding_InSelect() throws Exception {
    testPlanOneExcludedPattern("select columns[0], 3+5 from cp.`functions/interp/test_input.csv`",
        "EXPR\\$[0-9]+=\\[\\+\\(3, 5\\)\\]");
  }
}
