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

import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.sqoop.SqoopOptions;

import com.cloudera.sqoop.lib.SqoopRecord;

/**
 * Insert into an Oracle table based on emitted keys.
 */
public class OraOopOutputFormatInsert<K extends SqoopRecord, V> extends
    OraOopOutputFormatBase<K, V> {

  private static final OraOopLog LOG = OraOopLogFactory
      .getLog(OraOopOutputFormatInsert.class);

  /**
   * Type of insert to use - direct or partition exchange load.
   */
  public enum InsertMode {
    DirectInsert, ExchangePartition
  }

  @Override
  public RecordWriter<K, V> getRecordWriter(TaskAttemptContext context)
      throws IOException {
    OraOopUtilities.checkJavaSecurityEgd();
    Configuration conf = context.getConfiguration();

    int mapperId = this.getMapperId(context);
    applyMapperJdbcUrl(context, mapperId);

    // Is each mapper inserting rows into a unique table?...
    InsertMode insertMode = OraOopUtilities.getExportInsertMode(conf);

    // Should we use the APPEND_VALUES Oracle hint?...
    boolean useAppendValuesOracleHint = false;
    if (insertMode == InsertMode.ExchangePartition) {
      // NB: "Direct inserts" cannot utilize APPEND_VALUES, otherwise Oracle
      // will serialize
      // the N mappers, causing a lot of lock contention.
      useAppendValuesOracleHint = this.canUseOracleAppendValuesHint(context);
    }

    // Has the user forced the use of APPEND_VALUES either on or off?...
    useAppendValuesOracleHint =
        allowUserToOverrideUseOfTheOracleAppendValuesHint(context,
            useAppendValuesOracleHint);

    // If using APPEND_VALUES, check the batch size and commit frequency...
    if (useAppendValuesOracleHint) {
      updateBatchSizeInConfigurationToAllowOracleAppendValuesHint(context);
    }

    // Create the Record Writer...
    OraOopDBRecordWriterInsert result = null;
    try {
      result =
          new OraOopDBRecordWriterInsert(context, mapperId, insertMode,
              useAppendValuesOracleHint);
    } catch (NoClassDefFoundError ex) {
      throw new IOException(String.format(
          "Unable to create an instance of OraOopDBRecordWriterInsert.\n"
              + "The classpath is:\n%s", OraOopUtilities.getJavaClassPath()),
          ex);
    } catch (Exception ex) {
      throw new IOException(ex);
    }

    try {
      result.getExportTableAndColumns(context);
    } catch (SQLException ex) {
      throw new IOException(ex);
    }

    return result;
  }

  /**
   * Insert into an Oracle table based on emitted keys.
   */
  public class OraOopDBRecordWriterInsert extends OraOopDBRecordWriterBase {

    private String sqlStatement; // <- The SQL used when inserting batches of
                                 // rows into the Oracle table
    private InsertMode insertMode; // <- The modus operandi of this class. i.e.
                                   // Whether we insert into the Oracle table
                                   // directly, or insert data into a separate
                                   // table and then perform an EXCHANGE
                                   // PARTITION statement.
    private boolean useAppendValuesOracleHint; // <- Whether to use the
                                               // " /*+APPEND_VALUES*/ " hint
                                               // within the Oracle SQL
                                               // statement we generate
    private String subPartitionName; // <- The name of the subpartition in the
                                     // "main table" that this mappers unique
                                     // table will be exchanged with

    public OraOopDBRecordWriterInsert(TaskAttemptContext context, int mapperId,
        InsertMode insertMode, boolean useAppendValuesOracleHint)
        throws ClassNotFoundException, SQLException {

      super(context, mapperId);
      this.insertMode = insertMode;
      this.useAppendValuesOracleHint = useAppendValuesOracleHint;
    }

    @Override
    protected void getExportTableAndColumns(TaskAttemptContext context)
        throws SQLException {

      Configuration conf = context.getConfiguration();

      switch (this.insertMode) {

        case DirectInsert:
          super.getExportTableAndColumns(context);
          break;

        case ExchangePartition:
          // This mapper inserts data into a unique table before exchanging it
          // into
          // a subpartition of the 'real' export table...

          this.oracleTable = createUniqueMapperTable(context);
          setOracleTableColumns(OraOopOracleQueries.getTableColumns(
            this.getConnection(),
            this.oracleTable,
            OraOopUtilities.omitLobAndLongColumnsDuringImport(conf),
            OraOopUtilities.recallSqoopJobType(conf),
            true, // <- onlyOraOopSupportedTypes
            false, // <- omitOraOopPseudoColumns
            OracleUtils.isOracleEscapingDisabled(conf))
          );

          this.subPartitionName =
              OraOopUtilities.generateExportTableSubPartitionName(
                  this.mapperId, this.getJobSysDate(context), conf);

          break;

        default:
          throw new RuntimeException(String.format(
              "Update %s to cater for the insertMode \"%s\".", OraOopUtilities
                  .getCurrentMethodName(), this.insertMode.toString()));
      }

    }

    @Override
    public void closeConnection(TaskAttemptContext context)
        throws SQLException {

      // If this mapper is inserting data into a unique table, we'll now
      // move this data into the main export table...
      if (this.insertMode == InsertMode.ExchangePartition) {

        // Perform an "exchange subpartition" operation on the "main table"
        // to convert this table into a subpartition of the "main table"...
        exchangePartitionUniqueMapperTableDataIntoMainExportTable(context);

        LOG.debug(String.format("Dropping temporary mapper table %s",
            this.oracleTable.toString()));
        OraOopOracleQueries.dropTable(this.getConnection(), this.oracleTable);
      }

      super.closeConnection(context);
    }

    private void exchangePartitionUniqueMapperTableDataIntoMainExportTable(
        TaskAttemptContext context) throws SQLException {

      String schema =
          context.getConfiguration().get(OraOopConstants.ORAOOP_TABLE_OWNER);
      String localTableName =
          context.getConfiguration().get(OraOopConstants.ORAOOP_TABLE_NAME);
      OracleTable mainTable = new OracleTable(schema, localTableName);

      try {
        long start = System.nanoTime();

        OraOopOracleQueries.exchangeSubpartition(this.getConnection(),
            mainTable, this.subPartitionName, this.oracleTable);

        double timeInSec = (System.nanoTime() - start) / Math.pow(10, 9);
        LOG.info(String
            .format(
                "Time spent performing an \"exchange subpartition with "
                + "table\": %f sec.",
                timeInSec));
      } catch (SQLException ex) {
        throw new SQLException(
            String
                .format(
                    "Unable to perform an \"exchange subpartition\" operation "
                        + "for the table %s, for the subpartition named "
                        + "\"%s\" with the table named \"%s\".",
                    mainTable.toString(), this.subPartitionName,
                    this.oracleTable.toString()), ex);
      }
    }

    @Override
    protected String getBatchSqlStatement() {

      if (sqlStatement == null) {
        this.sqlStatement =
            getBatchInsertSqlStatement(this.useAppendValuesOracleHint
                ? "/*+APPEND_VALUES*/" : "");
      }

      return this.sqlStatement;
    }

    @Override
    void configurePreparedStatement(PreparedStatement statement,
        List<SqoopRecord> userRecords) throws SQLException {

      try {
        for (SqoopRecord sqoopRecord : userRecords) {
          int fieldCount = sqoopRecord.write(statement, 0);
          if (this.tableHasMapperRowNumberColumn) {
            statement.setLong(fieldCount + 1, this.mapperRowNumber);
            this.mapperRowNumber++;
          }
          statement.addBatch();
        }
      } catch (Exception ex) {
        if (ex instanceof SQLException) {
          throw (SQLException) ex;
        } else {
          LOG.error(String.format("The following error occurred during %s",
              OraOopUtilities.getCurrentMethodName()), ex);
          throw new SQLException(ex);
        }
      }

    }

  }

}
