/**
 * 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.sqoop.manager.mysql;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.sqoop.manager.ConnManager;
import org.apache.sqoop.manager.DirectMySQLManager;
import org.apache.sqoop.manager.MySQLManager;
import org.apache.sqoop.SqoopOptions;
import org.apache.sqoop.testutil.CommonArgs;
import org.apache.sqoop.testutil.ImportJobTestCase;
import org.apache.sqoop.util.FileListing;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * Test the DirectMySQLManager implementation.
 * This differs from MySQLManager only in its importTable() method, which
 * uses mysqldump instead of mapreduce+DBInputFormat.
 *
 * Since this requires a MySQL installation on your local machine to use, this
 * class is named in such a way that Hadoop's default QA process does not run
 * it. You need to run this manually with -Dtestcase=DirectMySQLTest.
 *
 * You need to put MySQL's Connector/J JDBC driver library into a location
 * where Hadoop will be able to access it (since this library cannot be checked
 * into Apache's tree for licensing reasons).
 *
 * You should also create a database named 'sqooptestdb' and authorize yourself:
 *
 * CREATE DATABASE sqooptestdb;
 * use mysql;
 * GRANT ALL PRIVILEGES ON sqooptestdb.* TO 'yourusername'@'localhost';
 * flush privileges;
 *
 */
public class DirectMySQLTest extends ImportJobTestCase {

  public static final Log LOG = LogFactory.getLog(
      DirectMySQLTest.class.getName());

  static final String TABLE_PREFIX = "EMPLOYEES_MYSQL_";

  // instance variables populated during setUp, used during tests
  private DirectMySQLManager manager;
  private MySQLTestUtils mySQLTestUtils = new MySQLTestUtils();

  @Override
  protected String getTablePrefix() {
    return TABLE_PREFIX;
  }

  @Before
  public void setUp() {
    super.setUp();

    SqoopOptions options = new SqoopOptions(mySQLTestUtils.getMySqlConnectString(),
        getTableName());
    options.setUsername(mySQLTestUtils.getUserName());
    mySQLTestUtils.addPasswordIfIsSet(options);

    LOG.debug("Setting up another DirectMySQLTest: "
        + mySQLTestUtils.getMySqlConnectString());

    manager = new DirectMySQLManager(options);

    Connection connection = null;
    Statement st = null;

    try {
      connection = manager.getConnection();
      connection.setAutoCommit(false);
      st = connection.createStatement();

      // create the database table and populate it with data.
      st.executeUpdate("DROP TABLE IF EXISTS " + getTableName());
      st.executeUpdate("CREATE TABLE " + getTableName() + " ("
          + "id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
          + "name VARCHAR(24) NOT NULL, "
          + "overly_large_number INT UNSIGNED,"
          + "start_date DATE, "
          + "salary FLOAT, "
          + "dept VARCHAR(32))");

      st.executeUpdate("INSERT INTO " + getTableName() + " VALUES("
          + "NULL,'Aaron',0,'2009-05-14',1000000.00,'engineering')");
      st.executeUpdate("INSERT INTO " + getTableName() + " VALUES("
          + "NULL,'Bob',100,'2009-04-20',400.00,'sales')");
      st.executeUpdate("INSERT INTO " + getTableName() + " VALUES("
          + "NULL,'Fred',4000000000,'2009-01-23',15.00,'marketing')");
      connection.commit();
    } catch (SQLException sqlE) {
      LOG.error("Encountered SQL Exception: " + sqlE);
      sqlE.printStackTrace();
      fail("SQLException when running test setUp(): " + sqlE);
    }
  }

  @After
  public void tearDown() {
    try {
      Statement stmt = manager.getConnection().createStatement();
      stmt.execute("DROP TABLE " + getTableName());
    } catch(SQLException e) {
      LOG.error("Can't clean up the database:", e);
    }

    super.tearDown();
  }

  private String [] getArgv(boolean mysqlOutputDelims, boolean isDirect,
      String tableName, String... extraArgs) {
    ArrayList<String> args = new ArrayList<String>();

    CommonArgs.addHadoopFlags(args);

    args.add("--table");
    args.add(tableName);
    args.add("--warehouse-dir");
    args.add(getWarehouseDir());
    args.add("--connect");
    args.add(mySQLTestUtils.getMySqlConnectString());
    if (isDirect) {
      args.add("--direct");
    }
    args.add("--username");
    args.add(mySQLTestUtils.getUserName());
    mySQLTestUtils.addPasswordIfIsSet(args);
    args.add("--where");
    args.add("id > 1");
    args.add("--num-mappers");
    args.add("1");

    if (mysqlOutputDelims) {
      args.add("--mysql-delimiters");
    }

    if (null != extraArgs) {
      for (String arg : extraArgs) {
        args.add(arg);
      }
    }

    return args.toArray(new String[0]);
  }

  private void doImport(boolean mysqlOutputDelims, boolean isDirect,
      String tableName, String [] expectedResults, String [] extraArgs)
      throws IOException {

    Path warehousePath = new Path(this.getWarehouseDir());
    Path tablePath = new Path(warehousePath, tableName);

    Path filePath = new Path(tablePath, "part-m-00000");

    File tableFile = new File(tablePath.toString());
    if (tableFile.exists() && tableFile.isDirectory()) {
      // remove the directory before running the import.
      FileListing.recursiveDeleteDir(tableFile);
    }

    String [] argv = getArgv(mysqlOutputDelims, isDirect, tableName, extraArgs);
    runImport(argv);

    File f = new File(filePath.toString());
    assertTrue("Could not find imported data file: " + f, f.exists());
    BufferedReader r = null;
    try {
      // Read through the file and make sure it's all there.
      r = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
      for (String expectedLine : expectedResults) {
        assertEquals(expectedLine, r.readLine());
      }
    } catch (IOException ioe) {
      LOG.error("Got IOException verifying results: " + ioe.toString());
      ioe.printStackTrace();
      fail(ioe.toString());
    } finally {
      IOUtils.closeStream(r);
    }
  }

  @Test
  public void testDirectBulkImportWithDefaultDelims() throws IOException {
    // no quoting of strings allowed.
    String [] expectedResults = {
      "2,Bob,100,2009-04-20,400,sales",
      "3,Fred,4000000000,2009-01-23,15,marketing",
    };

    doImport(false, true, getTableName(), expectedResults, null);
  }

  @Test
  public void testWithExtraParams() throws IOException {
    // no quoting of strings allowed.
    String [] expectedResults = {
      "2,Bob,100,2009-04-20,400,sales",
      "3,Fred,4000000000,2009-01-23,15,marketing",
    };

    String [] extraArgs = { "--", "--lock-tables" };

    doImport(false, true, getTableName(), expectedResults, extraArgs);
  }

  @Test
  public void testMultiMappers() throws IOException {
    // no quoting of strings allowed.
    String [] expectedResults = {
      "2,Bob,100,2009-04-20,400,sales",
      "3,Fred,4000000000,2009-01-23,15,marketing",
    };

    String [] extraArgs = { "-m", "2" };

    doImport(false, true, getTableName(), expectedResults, extraArgs);
  }

  @Test
  public void testJdbcColumnSubset() throws IOException {
    // Test that column subsets work in JDBC mode.
    LOG.info("Starting JDBC Column Subset test.");

    String [] expectedResults = {
      "2,Bob,400.0",
      "3,Fred,15.0",
    };

    String [] extraArgs = { "--columns", "id,name,salary" };
    doImport(false, false, getTableName(), expectedResults, extraArgs);
  }

  @Test
  public void testDirectColumnSubset() throws IOException {
    // Using a column subset should actually force direct mode off, but this
    // should just warn the user and do a normal import.
    LOG.info("Starting Direct Column Subset test.");

    String [] expectedResults = {
      "2,Bob,400.0",
      "3,Fred,15.0",
    };

    String [] extraArgs = { "--columns", "id,name,salary" };
    doImport(false, true, getTableName(), expectedResults, extraArgs);
  }

  @Test
  public void testDirectBulkImportWithMySQLQuotes() throws IOException {
    // mysql quotes all string-based output.
    String [] expectedResults = {
      "2,'Bob',100,'2009-04-20',400,'sales'",
      "3,'Fred',4000000000,'2009-01-23',15,'marketing'",
    };

    doImport(true, true, getTableName(), expectedResults, null);
  }

  @Test
  public void testMySQLJdbcImport() throws IOException {
    String [] expectedResults = {
      "2,Bob,100,2009-04-20,400.0,sales",
      "3,Fred,4000000000,2009-01-23,15.0,marketing",
    };

    doImport(false, false, getTableName(), expectedResults, null);
  }

  @Test
  public void testJdbcEscapedTableName() throws Exception {
    // Test a JDBC-based import of a table whose name is
    // a reserved sql keyword (and is thus `quoted`)
    final String RESERVED_TABLE_NAME = "TABLE";
    SqoopOptions options = new SqoopOptions(mySQLTestUtils.getMySqlConnectString(),
        RESERVED_TABLE_NAME);
    options.setUsername(mySQLTestUtils.getUserName());
    mySQLTestUtils.addPasswordIfIsSet(options);
    ConnManager mgr = new MySQLManager(options);

    Connection connection = null;
    Statement st = null;

    try {
      connection = mgr.getConnection();
      connection.setAutoCommit(false);
      st = connection.createStatement();

      // create the database table and populate it with data.
      st.executeUpdate("DROP TABLE IF EXISTS `" + RESERVED_TABLE_NAME + "`");
      st.executeUpdate("CREATE TABLE `" + RESERVED_TABLE_NAME + "` ("
          + "id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
          + "name VARCHAR(24) NOT NULL, "
          + "start_date DATE, "
          + "salary FLOAT, "
          + "dept VARCHAR(32))");

      st.executeUpdate("INSERT INTO `" + RESERVED_TABLE_NAME + "` VALUES("
          + "2,'Aaron','2009-05-14',1000000.00,'engineering')");
      st.close();
      connection.commit();

      String [] expectedResults = {
          "2,Aaron,2009-05-14,1000000.0,engineering",
      };

      doImport(false, false, RESERVED_TABLE_NAME, expectedResults, null);

      st = connection.createStatement();
      st.execute("DROP TABLE `" + RESERVED_TABLE_NAME + "`");
    } finally {
      if (null != st) {
        st.close();
      }

      if (null != connection) {
        connection.close();
      }
    }

  }

  @Test(expected = IOException.class)
  public void testSqoopNullStringValueFailsValidate() throws Exception {
    String [] expectedResults =  {};
    String [] extraArgs =  {"--null-string", "abc"};

    doImport(false, true, getTableName(), expectedResults, extraArgs);
  }

  @Test(expected = IOException.class)
  public void testSqoopNullNonStringValueFailsValidate() throws Exception {
    String [] expectedResults =  {};
    String [] extraArgs =  {"--null-non-string", "abc"};

    doImport(false, true, getTableName(), expectedResults, extraArgs);
  }

  @Test
  public void testJdbcEscapedColumnName() throws Exception {
    // Test a JDBC-based import of a table with a column whose name is
    // a reserved sql keyword (and is thus `quoted`).
    final String TABLE_NAME = "mysql_escaped_col_table";
    SqoopOptions options = new SqoopOptions(mySQLTestUtils.getMySqlConnectString(),
        TABLE_NAME);
    options.setUsername(mySQLTestUtils.getUserName());
    mySQLTestUtils.addPasswordIfIsSet(options);
    ConnManager mgr = new MySQLManager(options);

    Connection connection = null;
    Statement st = null;

    try {
      connection = mgr.getConnection();
      connection.setAutoCommit(false);
      st = connection.createStatement();

      // create the database table and populate it with data.
      st.executeUpdate("DROP TABLE IF EXISTS " + TABLE_NAME);
      st.executeUpdate("CREATE TABLE " + TABLE_NAME + " ("
          + "id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
          + "`table` VARCHAR(24) NOT NULL, "
          + "`CREATE` DATE, "
          + "salary FLOAT, "
          + "dept VARCHAR(32))");

      st.executeUpdate("INSERT INTO " + TABLE_NAME + " VALUES("
          + "2,'Aaron','2009-05-14',1000000.00,'engineering')");
      st.close();
      connection.commit();

      String [] expectedResults = {
          "2,Aaron,2009-05-14,1000000.0,engineering",
      };

      doImport(false, false, TABLE_NAME, expectedResults, null);

      st = connection.createStatement();
      st.execute("DROP TABLE " + TABLE_NAME);
    } finally {
      if (null != st) {
        st.close();
      }

      if (null != connection) {
        connection.close();
      }
    }
  }
}
