/**
 * 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.tajo.cli.tsql;

import com.google.common.io.NullOutputStream;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.PosixParser;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.tajo.ConfigKey;
import org.apache.tajo.SessionVars;
import org.apache.tajo.TajoTestingCluster;
import org.apache.tajo.TpchTestBase;
import org.apache.tajo.catalog.CatalogUtil;
import org.apache.tajo.catalog.TableDesc;
import org.apache.tajo.client.ClientParameters;
import org.apache.tajo.client.QueryStatus;
import org.apache.tajo.client.TajoClient;
import org.apache.tajo.conf.TajoConf;
import org.apache.tajo.rpc.RpcConstants;
import org.apache.tajo.storage.StorageUtil;
import org.apache.tajo.storage.TablespaceManager;
import org.apache.tajo.util.FileUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;

import java.io.*;
import java.net.URL;
import java.util.Properties;

import static org.junit.Assert.*;

public class TestTajoCli {
  protected static final TpchTestBase testBase;
  protected static final TajoTestingCluster cluster;

  /** the base path of result directories */
  protected static final Path resultBasePath;
  static {
    testBase = TpchTestBase.getInstance();
    cluster = testBase.getTestingCluster();
    URL resultBaseURL = ClassLoader.getSystemResource("results");
    resultBasePath = new Path(resultBaseURL.toString());
  }

  private TajoCli tajoCli;
  private Path currentResultPath;
  private ByteArrayOutputStream out;

  @Rule
  public TestName name = new TestName();

  public TestTajoCli() {
    String className = getClass().getSimpleName();
    currentResultPath = new Path(resultBasePath, className);
  }

  @Before
  public void setUp() throws Exception {
    out = new ByteArrayOutputStream();
    Properties connParams = new Properties();
    connParams.setProperty(RpcConstants.CLIENT_RETRY_NUM, "3");
    tajoCli = new TajoCli(cluster.getConfiguration(), new String[]{}, connParams, System.in, out);
  }

  @After
  public void tearDown() throws IOException {
    out.close();
    if (tajoCli != null) {
      tajoCli.close();
    }
  }

  private static void setVar(TajoCli cli, ConfigKey key, String val) throws Exception {
    cli.executeMetaCommand("\\set " + key.keyname() + " " + val);
  }

  private static void assertSessionVar(TajoCli cli, String key, String expectedVal) {
    assertEquals(cli.getContext().getCliSideVar(key), expectedVal);
  }

  private void assertOutputResult(String actual) throws Exception {
    assertOutputResult(name.getMethodName() + ".result", actual);
  }

  private void assertOutputResult(String expectedResultFile, String actual) throws Exception {
    assertOutputResult(expectedResultFile, actual, null, null);
  }

  private void assertOutputResult(String expectedResultFile, String actual, String[] paramKeys, String[] paramValues)
    throws Exception {
    FileSystem fs = currentResultPath.getFileSystem(testBase.getTestingCluster().getConfiguration());
    Path resultFile = StorageUtil.concatPath(currentResultPath, expectedResultFile);
    assertTrue(resultFile.toString() + " existence check", fs.exists(resultFile));

    String expectedResult = FileUtil.readTextFile(new File(resultFile.toUri()));

    if (paramKeys != null) {
      for (int i = 0; i < paramKeys.length; i++) {
        if (i < paramValues.length) {
          expectedResult = expectedResult.replace(paramKeys[i], paramValues[i]);
        }
      }
    }
    assertEquals(expectedResult.trim(), actual.trim());
  }

  @Test
  public void testParseParam() throws Exception {
    String[] args = new String[]{"-f", "test.sql", "--param", "test1=10", "--param", "test2=20"};

    CommandLineParser parser = new PosixParser();
    CommandLine cmd = parser.parse(TajoCli.options, args);

    String fileName = cmd.getOptionValue("f");
    assertNotNull(fileName);
    assertEquals(args[1], fileName);

    String[] paramValues = cmd.getOptionValues("param");

    assertNotNull(paramValues);
    assertEquals(2, paramValues.length);

    assertEquals("test1=10", paramValues[0]);
    assertEquals("test2=20", paramValues[1]);
  }

  @Test
  public void testParseConf() throws Exception {
    String[] args = new String[]{"--conf", "tajo.cli.print.pause=false",
      "--conf", "tajo.executor.join.inner.in-memory-table-num=256"};

    CommandLineParser parser = new PosixParser();
    CommandLine cmd = parser.parse(TajoCli.options, args);
    String[] confValues = cmd.getOptionValues("conf");

    assertNotNull(confValues);
    assertEquals(2, confValues.length);

    assertEquals("tajo.cli.print.pause=false", confValues[0]);
    assertEquals("tajo.executor.join.inner.in-memory-table-num=256", confValues[1]);

    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
    TajoCli testCli = new TajoCli(tajoConf, args, null, System.in, System.out);
    try {
      assertEquals("false", testCli.getContext().get(SessionVars.CLI_PAGING_ENABLED));
      assertEquals("256", testCli.getContext().getConf().get("tajo.executor.join.inner.in-memory-table-num"));
    } finally {
      testCli.close();
    }
  }

  @Test
  public void testReplaceParam() throws Exception {
    String sql = "select * from lineitem where l_tax > ${tax} and l_returnflag > '${returnflag}'";
    String[] params = new String[]{"tax=10", "returnflag=A"};


    String expected = "select * from lineitem where l_tax > 10 and l_returnflag > 'A'";
    assertEquals(expected, TajoCli.replaceParam(sql, params));
  }

  @Test
  public void testLocalQueryWithoutFrom() throws Exception {
    String sql = "select 'abc', '123'; select substr('123456', 1,3);";
    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
    tajoCli.executeScript(sql);
    String consoleResult = new String(out.toByteArray());

    assertOutputResult(consoleResult);
  }

  @Test
  public void testConnectDatabase() throws Exception {
    String databaseName;

    if (cluster.isHiveCatalogStoreRunning()) {
      databaseName = "TEST_CONNECTION_DATABASE".toLowerCase();
    } else {
      databaseName = "TEST_CONNECTION_DATABASE";
    }
    String sql = "create database \"" + databaseName + "\";";

    tajoCli.executeScript(sql);

    tajoCli.executeMetaCommand("\\c " + databaseName);
    assertEquals(databaseName, tajoCli.getContext().getCurrentDatabase());

    tajoCli.executeMetaCommand("\\c default");
    assertEquals("default", tajoCli.getContext().getCurrentDatabase());

    tajoCli.executeMetaCommand("\\c \"" + databaseName + "\"");
    assertEquals(databaseName, tajoCli.getContext().getCurrentDatabase());
  }

  private void verifyDescTable(String sql, String tableName, String resultFileName) throws Exception {
    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
    tajoCli.executeScript(sql);

    tajoCli.executeMetaCommand("\\d " + tableName);
    tajoCli.executeMetaCommand("\\d \"" + tableName + "\"");

    String consoleResult = new String(out.toByteArray());

    if (!cluster.isHiveCatalogStoreRunning()) {
      assertOutputResult(resultFileName, consoleResult, new String[]{"${table.path}"},
        new String[]{TablespaceManager.getDefault().getTableUri("default", tableName).toString()});
    }
  }

  @Test
  public void testDescTable() throws Exception {
    String tableName;
    if (cluster.isHiveCatalogStoreRunning()) {
      tableName = "TEST_DESC_TABLE".toLowerCase();
    } else {
      tableName = "TEST_DESC_TABLE";
    }

    String sql = "create table \"" + tableName + "\" (col1 int4, col2 int4);";
    verifyDescTable(sql, tableName, "testDescTable.result");
  }

  @Test
  public void testDescTableForNestedSchema() throws Exception {
    String tableName;
    if (cluster.isHiveCatalogStoreRunning()) {
      tableName = "TEST_DESC_TABLE_NESTED".toLowerCase();
    } else {
      tableName = "TEST_DESC_TABLE_NESTED";
    }

    String sql = "create table \"" + tableName + "\" (col1 int4, col2 int4, col3 record (col4 record (col5 text)));";
    verifyDescTable(sql, tableName, "testDescTableForNestedSchema.result");
  }

  @Test
  public void testSelectResultWithNullFalse() throws Exception {
    String sql =
      "select\n" +
        "  c_custkey,\n" +
        "  orders.o_orderkey,\n" +
        "  orders.o_orderstatus \n" +
        "from\n" +
        "  orders full outer join customer on c_custkey = o_orderkey\n" +
        "order by\n" +
        "  c_custkey,\n" +
        "  orders.o_orderkey;\n";

    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
    tajoCli.executeScript(sql);

    String consoleResult = new String(out.toByteArray());
    assertOutputResult(consoleResult);
  }

  private void verifySelectResultWithNullTrue() throws Exception {
    String sql =
      "select\n" +
        "  c_custkey,\n" +
        "  orders.o_orderkey,\n" +
        "  orders.o_orderstatus \n" +
        "from\n" +
        "  orders full outer join customer on c_custkey = o_orderkey\n" +
        "order by\n" +
        "  c_custkey,\n" +
        "  orders.o_orderkey;\n";


    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
    assertSessionVar(tajoCli, SessionVars.CLI_NULL_CHAR.keyname(), "testnull");

    tajoCli.executeScript(sql);

    String consoleResult = new String(out.toByteArray());
    assertOutputResult(consoleResult);
  }

  @Test
  public void testSelectResultWithNullTrueDeprecated() throws Exception {
    setVar(tajoCli, TajoConf.ConfVars.$CLI_NULL_CHAR, "testnull");
    verifySelectResultWithNullTrue();
  }

  @Test
  public void testSelectResultWithNullTrue() throws Exception {
    setVar(tajoCli, SessionVars.CLI_NULL_CHAR, "testnull");
    verifySelectResultWithNullTrue();
  }

  private void verifyStopWhenError() throws Exception {
    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());

    assertSessionVar(tajoCli, SessionVars.ON_ERROR_STOP.keyname(), "true");

    tajoCli.executeScript("select count(*) from lineitem; " +
      "select count(*) from lineitem2; " +
      "select count(*) from orders");

    String consoleResult = new String(out.toByteArray());
    assertOutputResult(consoleResult);
  }

  @Test
  public void testGetConf() throws Exception {
    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    TajoCli tajoCli = new TajoCli(tajoConf, new String[]{}, null, System.in, out);
    try {
      tajoCli.executeMetaCommand("\\getconf tajo.rootdir");

      String consoleResult = new String(out.toByteArray());
      assertEquals(consoleResult, tajoCli.getContext().getConf().getVar(TajoConf.ConfVars.ROOT_DIR) + "\n");
    } finally {
      tajoCli.close();
    }
  }

  @Test
  public void testShowMasters() throws Exception {
    TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration();
    setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    TajoCli tajoCli = new TajoCli(tajoConf, new String[]{}, null, System.in, out);
    tajoCli.executeMetaCommand("\\admin -showmasters");

    String consoleResult = new String(out.toByteArray());

    String masterAddress = tajoCli.getContext().getConf().getVar(TajoConf.ConfVars.TAJO_MASTER_UMBILICAL_RPC_ADDRESS);
    String host = masterAddress.split(":")[0];
    tajoCli.close();
    assertEquals(consoleResult, host + "\n");
  }

  @Test
  public void testStopWhenErrorDeprecated() throws Exception {
    tajoCli.executeMetaCommand("\\set tajo.cli.error.stop true");
    verifyStopWhenError();
  }

  @Test
  public void testStopWhenError() throws Exception {
    tajoCli.executeMetaCommand("\\set ON_ERROR_STOP true");
    verifyStopWhenError();
  }

  @Test
  public void testRunWhenError() throws Exception {
    Thread t = new Thread() {
      public void run() {
        try {
          PipedOutputStream po = new PipedOutputStream();
          InputStream is = new PipedInputStream(po);
          ByteArrayOutputStream out = new ByteArrayOutputStream();

          TajoConf tajoConf = new TajoConf();
          setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
          Properties connParams = new Properties();
          connParams.setProperty(ClientParameters.RETRY, "3");
          TajoCli tc = new TajoCli(tajoConf, new String[]{}, connParams, is, out);

          tc.executeMetaCommand("\\set ON_ERROR_STOP false");
          assertSessionVar(tc, SessionVars.ON_ERROR_STOP.keyname(), "false");

          po.write(new String("asdf;\nqwe;\nzxcv;\n").getBytes());

          tc.runShell();
        } catch (Exception e) {
          throw new RuntimeException("Cannot run thread in testRunWhenError", e);
        }
      }
    };

    t.start();
    Thread.sleep(1000);
    if(!t.isAlive()) {
      fail("TSQL should be alive");
    } else {
      t.interrupt();
      t.join();
    }
  }

  @Test
  public void testHelpSessionVars() throws Exception {
    tajoCli.executeMetaCommand("\\help set");
    assertOutputResult(new String(out.toByteArray()));
  }

  @Test
  public void testTimeZoneSessionVars1() throws Exception {
    tajoCli.executeMetaCommand("\\set TIMEZONE GMT+1");
    tajoCli.executeMetaCommand("\\set");
    String output = new String(out.toByteArray());
    assertTrue(output.contains("'TIMEZONE'='GMT+1'"));
  }

  @Test
  public void testTimeZoneSessionVars2() throws Exception {
    tajoCli.executeScript("SET TIME ZONE 'GMT+2'");
    tajoCli.executeMetaCommand("\\set");
    String output = new String(out.toByteArray());
    assertTrue(output.contains("'TIMEZONE'='GMT+2'"));
  }

  @Test
  public void testTimeZoneTest1() throws Exception {
    String tableName = "test1";
    tajoCli.executeMetaCommand("\\set TIMEZONE GMT+0");
    tajoCli.executeScript("create table " + tableName + " (col1 TIMESTAMP)");
    tajoCli.executeScript("insert into " + tableName + " select to_timestamp(0)");
    tajoCli.executeScript("select * from " + tableName);
    String consoleResult = new String(out.toByteArray());
    tajoCli.executeScript("DROP TABLE " + tableName + " PURGE");
    assertTrue(consoleResult.contains("1970-01-01 00:00:00"));
  }

  @Test
  public void testTimeZoneTest2() throws Exception {
    String tableName = "test1";
    tajoCli.executeMetaCommand("\\set TIMEZONE GMT+1");
    tajoCli.executeScript("create table " + tableName + " (col1 TIMESTAMP)");
    tajoCli.executeScript("insert into " + tableName + " select to_timestamp(0)");
    tajoCli.executeScript("select * from " + tableName);
    String consoleResult = new String(out.toByteArray());
    tajoCli.executeScript("DROP TABLE " + tableName + " PURGE");
    assertTrue(consoleResult.contains("1970-01-01 00:00:00"));
  }

  @Test(timeout = 3000)
  public void testNonForwardQueryPause() throws Exception {
    final String sql = "select * from default.lineitem";
    TajoCli cli = null;
    try {
      TableDesc tableDesc = cluster.getMaster().getCatalog().getTableDesc("default", "lineitem");
      assertNotNull(tableDesc);
      assertEquals(0L, tableDesc.getStats().getNumRows().longValue());

      InputStream testInput = new ByteArrayInputStream(new byte[]{(byte) DefaultTajoCliOutputFormatter.QUIT_COMMAND});
      cli = new TajoCli(cluster.getConfiguration(), new String[]{}, null, testInput, out);
      setVar(cli, SessionVars.CLI_PAGE_ROWS, "2");
      setVar(cli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());

      cli.executeScript(sql);

      String consoleResult;
      consoleResult = new String(out.toByteArray());
      assertOutputResult(consoleResult);
    } finally {
      cli.close();
    }
  }

  @Test
  public void testResultRowNumWhenSelectingOnPartitionedTable() throws Exception {
    try (TajoCli cli2 = new TajoCli(cluster.getConfiguration(), new String[]{}, null, System.in,
        new NullOutputStream())) {
      cli2.executeScript("create table region_part (r_regionkey int8, r_name text) " +
          "partition by column (r_comment text) as select * from region");

      setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName());
      tajoCli.executeScript("select r_comment from region_part where r_comment = 'hs use ironic, even requests. s'");
      String consoleResult = new String(out.toByteArray());
      assertOutputResult(consoleResult);
    } finally {
      tajoCli.executeScript("drop table region_part purge");
    }
  }

  // TODO: This should be removed at TAJO-1891
  @Test
  public void testAddPartitionNotimplementedException() throws Exception {
    String tableName = CatalogUtil.normalizeIdentifier("testAddPartitionNotimplementedException");
    tajoCli.executeScript("create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8)");
    tajoCli.executeScript("alter table " + tableName + " add partition (key2 = 0.1)");

    String consoleResult;
    consoleResult = new String(out.toByteArray());
    assertOutputResult(consoleResult);
  }

  // TODO: This should be added at TAJO-1891
  public void testAlterTableAddDropPartition() throws Exception {
    String tableName = CatalogUtil.normalizeIdentifier("testAlterTableAddPartition");

    tajoCli.executeScript("create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8)");
    tajoCli.executeScript("alter table " + tableName + " add partition (key2 = 0.1)");
    tajoCli.executeScript("alter table " + tableName + " add partition (key = 0.1)");
    tajoCli.executeScript("alter table " + tableName + " drop partition (key = 0.1)");
    tajoCli.executeScript("alter table " + tableName + " drop partition (key = 0.1)");

    tajoCli.executeScript("drop table " + tableName);
    tajoCli.executeScript("create table " + tableName
      + " (col1 int4, col2 int4) partition by column(col3 float8, col4 int4)");

    TajoClient client = testBase.getTestingCluster().newTajoClient();
    TableDesc tableDesc = client.getTableDesc(tableName);

    String partitionLocation = tableDesc.getUri().toString() + "/col5=0.1/col6=10";
    tajoCli.executeScript("alter table " + tableName + " add partition (col3 = 0.1, col4 = 10)"
      + " location '" + partitionLocation + "'");

    Path partitionPath = new Path(partitionLocation);
    FileSystem fs = testBase.getTestingCluster().getDefaultFileSystem();
    assertTrue(fs.exists(partitionPath));

    tajoCli.executeScript("alter table " + tableName + " drop partition (col3 = 0.1, col4 = 10)");

    String consoleResult = new String(out.toByteArray());
    assertOutputResult(consoleResult);
  }

  public static class TajoCliOutputTestFormatter extends DefaultTajoCliOutputFormatter {
    @Override
    protected String getResponseTimeReadable(float responseTime) {
      return "";
    }
    @Override
    public void printProgress(PrintWriter sout, QueryStatus status) {
      //nothing to do
    }
  }
}
