/**
 * 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.netezza;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Arrays;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.sqoop.manager.DirectNetezzaManager;
import org.junit.Test;

import org.apache.sqoop.SqoopOptions;

import static org.junit.Assert.fail;

/**
 * Test the DirectNetezzaManager implementation's exportJob() functionality.
 */
public class DirectNetezzaExportManualTest extends NetezzaExportManualTest {

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

  static final String TABLE_PREFIX = "EMPNZ_D_EXP";

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

  @Override
  protected boolean isDirectMode() {
    return true;
  }

  @Override
  protected String[] getCodeGenArgv(String... extraArgs) {

    String[] moreArgs = new String[extraArgs.length + 4];
    int i = 0;
    for (i = 0; i < extraArgs.length; i++) {
      moreArgs[i] = extraArgs[i];
    }

    // Add username argument for netezza.
    moreArgs[i++] = "--username";
    moreArgs[i++] = NetezzaTestUtils.getNZUser();
    moreArgs[i++] = "--password";
    moreArgs[i++] = NetezzaTestUtils.getNZPassword();

    return super.getCodeGenArgv(moreArgs);
  }

  @Override
  protected String[] getArgv(boolean includeHadoopFlags, int rowsPerStatement,
      int statementsPerTx, String... additionalArgv) {

    String[] argV = super.getArgv(includeHadoopFlags,
        rowsPerStatement, statementsPerTx);
    String[] subArgV = newStrArray(argV, "--direct",
      "--username",  NetezzaTestUtils.getNZUser(), "--password",
      NetezzaTestUtils.getNZPassword());
    String[] newArgV = new String[subArgV.length + additionalArgv.length];
    int i = 0;
    for (String s : subArgV) {
      newArgV[i++] = s;
    }
    for (String s: additionalArgv) {
      newArgV[i++] = s;
    }
    return newArgV;
  }


  /**
   * Create the table definition to export to, removing any prior table. By
   * specifying ColumnGenerator arguments, you can add extra columns to the
   * table of arbitrary type.
   */
  @Override
  public void createTable(ColumnGenerator... extraColumns)
    throws SQLException {
    NetezzaTestUtils.createTableNZ(conn, getTableName(), extraColumns);
  }

  /**
   * Creates the staging table.
   * @param extraColumns extra columns that go in the staging table
   * @throws SQLException if an error occurs during export
   */
  @Override
  public void createStagingTable(ColumnGenerator... extraColumns)
    throws SQLException {
    NetezzaTestUtils.createTableNZ(conn, getStagingTableName(), extraColumns);
  }



  protected void runNetezzaTest(String tableName, String[] argv,
    ColumnGenerator...extraCols) throws IOException {
    SqoopOptions options = new SqoopOptions(
        NetezzaTestUtils.getNZConnectString(), getTableName());
    options.setUsername(NetezzaTestUtils.getNZUser());
    options.setPassword(NetezzaTestUtils.getNZPassword());

    LOG.info("Running export with argv : " + Arrays.toString(argv));
    manager = new DirectNetezzaManager(options);

    try {
      createTable(extraCols);
      LOG.info("Created table " + tableName);
      createExportFile(extraCols);
      // run the export and verify that the results are good.
      runExport(argv);
      verifyExport(3, conn);
      if (extraCols.length > 0) {
        assertColMinAndMax(forIdx(0), extraCols[0]);
      }
    } catch (SQLException sqlE) {
      LOG.error("Encountered SQL Exception: " + sqlE);
      sqlE.printStackTrace();
      fail("SQLException when accessing target table. " + sqlE);
    }
  }

  /**
   * Test an authenticated export using netezza external table import.
   */
  @Test
  public void testSimpleExport() throws IOException, SQLException {
    String[] argv = getArgv(true, 10, 10);
    runNetezzaTest(getTableName(), argv);
  }

  @Test
  public void testValidExtraArgs() throws Exception {

    String [] extraArgs = {
        "--",
        "--log-dir", "/tmp",
        "--max-errors", "2",
        "--trunc-string",
        "--ctrl-chars"
     };
    String[] argv = getArgv(true, 10, 10, extraArgs);
    runNetezzaTest(getTableName(), argv);
  }

  @Test
  public void testNullStringExport() throws Exception {

    String [] extraArgs = {
        "--input-null-string", "\\\\N",
        "--input-null-non-string", "\\\\N",
        "--input-escaped-by", "\\",
    };
    ColumnGenerator[] extraCols = new ColumnGenerator[] {
       new NullColumnGenerator(),
    };

    String[] argv = getArgv(true, 10, 10, extraArgs);
    runNetezzaTest(getTableName(), argv, extraCols);
  }


  @Test
  public void testDifferentNullStrings() throws IOException, SQLException {
    ColumnGenerator[] extraCols = new ColumnGenerator[] {
        new NullColumnGenerator(),
    };

    String [] extraArgs = {
       "--input-null-string", "\\N",
       "--input-null-non-string", "\\M",
    };
    String[] argv = getArgv(true, 10, 10, extraArgs);
    try {
      runNetezzaTest(getTableName(), argv, extraCols);
      fail("Expected failure for different null strings");
    } catch(IOException ioe) {
      // success
    }
  }

  @Test(expected = java.io.IOException.class)
  public void testLongNullStrings() throws IOException, SQLException {
    ColumnGenerator[] extraCols = new ColumnGenerator[] {
        new NullColumnGenerator(),
    };

    String [] extraArgs = {
       "--input-null-string", "morethan4chars",
       "--input-null-non-string", "morethan4chars",
    };
    String[] argv = getArgv(true, 10, 10, extraArgs);
    try {
      runNetezzaTest(getTableName(), argv, extraCols);
      fail("Expected failure for long null strings");
    } catch(IOException ioe) {
      // success
    }
  }


  @Override
  @Test
  public void testMultiMapTextExportWithStaging() throws IOException,
      SQLException {
    // disable this test as staging is not supported in direct mode
  }

  @Override
  @Test
  public void testMultiTransactionWithStaging() throws IOException,
      SQLException {
    // disable this test as staging is not supported in direct mode
  }

  @Override
  @Test
  public void testColumnsExport() throws IOException, SQLException {
    // disable this test as it is not supported in direct mode
  }

  @Override
  @Test
  public void testSequenceFileExport() throws IOException, SQLException {
    // disable this test as it is not supported in direct mode
  }
}
