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

import org.apache.sqoop.SqoopOptions;
import org.apache.sqoop.testutil.ImportJobTestCase;
import org.apache.hadoop.conf.Configuration;
import org.apache.sqoop.tool.ImportTool;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

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

/**
 * Tests for RowCountValidator.
 */
public class RowCountValidatorImportTest extends ImportJobTestCase {

  protected List<String> getExtraArgs(Configuration conf) {
    ArrayList<String> list = new ArrayList<String>(1);
    list.add("--validate");
    return list;
  }

  /**
   * Test if the --validate flag actually made it through the options.
   *
   * @throws Exception
   */
  @Test
  public void testValidateOptionIsEnabledInCLI() throws Exception {
    String[] types = {"INT NOT NULL PRIMARY KEY", "VARCHAR(32)", "VARCHAR(32)"};
    String[] insertVals = {"1", "'Bob'", "'sales'"};

    try {
      createTableWithColTypes(types, insertVals);

      String[] args = getArgv(true, null, getConf());
      ArrayList<String> argsList = new ArrayList<String>();
      Collections.addAll(argsList, args);
      assertTrue("Validate option missing.", argsList.contains("--validate"));
    } finally {
      dropTableIfExists(getTableName());
    }
  }

  @Test
  public void testValidationOptionsParsedCorrectly() throws Exception {
    String[] types = {"INT NOT NULL PRIMARY KEY", "VARCHAR(32)", "VARCHAR(32)"};
    String[] insertVals = {"1", "'Bob'", "'sales'"};

    try {
      createTableWithColTypes(types, insertVals);

      String[] args = getArgv(true, null, getConf());
      ArrayList<String> argsList = new ArrayList<String>();
      argsList.add("--validator");
      argsList.add("org.apache.sqoop.validation.RowCountValidator");
      argsList.add("--validation-threshold");
      argsList.add("org.apache.sqoop.validation.AbsoluteValidationThreshold");
      argsList.add("--validation-failurehandler");
      argsList.add("org.apache.sqoop.validation.AbortOnFailureHandler");
      Collections.addAll(argsList, args);

      assertTrue("Validate option missing.", argsList.contains("--validate"));
      assertTrue("Validator option missing.", argsList.contains("--validator"));

      String[] optionArgs = toStringArray(argsList);

      SqoopOptions validationOptions = new ImportTool().parseArguments(
        optionArgs, getConf(), getSqoopOptions(getConf()), true);
      assertEquals(RowCountValidator.class,
        validationOptions.getValidatorClass());
      assertEquals(AbsoluteValidationThreshold.class,
        validationOptions.getValidationThresholdClass());
      assertEquals(AbortOnFailureHandler.class,
        validationOptions.getValidationFailureHandlerClass());
    } catch (Exception e) {
      fail("The validation options are passed correctly: " + e.getMessage());
    } finally {
      dropTableIfExists(getTableName());
    }
  }

  @Test
  public void testInvalidValidationOptions() throws Exception {
    String[] types = {"INT NOT NULL PRIMARY KEY", "VARCHAR(32)", "VARCHAR(32)"};
    String[] insertVals = {"1", "'Bob'", "'sales'"};

    try {
      createTableWithColTypes(types, insertVals);

      String[] args = getArgv(true, null, getConf());
      ArrayList<String> argsList = new ArrayList<String>();
      argsList.add("--validator");
      argsList.add("org.apache.sqoop.validation.NullValidator");
      argsList.add("--validation-threshold");
      argsList.add("org.apache.sqoop.validation.NullValidationThreshold");
      argsList.add("--validation-failurehandler");
      argsList.add("org.apache.sqoop.validation.NullFailureHandler");
      Collections.addAll(argsList, args);

      String[] optionArgs = toStringArray(argsList);

      new ImportTool().parseArguments(optionArgs, getConf(),
        getSqoopOptions(getConf()), true);
      fail("The validation options are incorrect and must throw an exception");
    } catch (Exception e) {
      System.out.println("e.getMessage() = " + e.getMessage());
      System.out.println("e.getClass() = " + e.getClass());
      assertEquals(SqoopOptions.InvalidOptionsException.class,
        e.getClass());
    } finally {
      dropTableIfExists(getTableName());
    }
  }

  private String[] toStringArray(ArrayList<String> argsList) {
    String[] optionArgs = new String[argsList.size()];
    for (int i = 0; i < argsList.size(); i++) {
      optionArgs[i] = argsList.get(i);
    }
    return optionArgs;
  }

  /**
   * Negative case where the row counts do NOT match.
   */
  @Test
  public void testValidatorWithDifferentRowCounts() {
    try {
      Validator validator = new RowCountValidator();
      validator.validate(new ValidationContext(100, 90));
      fail("FailureHandler should have thrown an exception");
    } catch (ValidationException e) {
      assertEquals("Validation failed by RowCountValidator. "
        + "Reason: The expected counter value was 100 but the actual value "
        + "was 90, Row Count at Source: 100, Row Count at Target: 90",
        e.getMessage());
    }
  }

  /**
   * Positive case where the row counts match.
   */
  @Test
  public void testValidatorWithMatchingRowCounts() {
    try {
      Validator validator = new RowCountValidator();
      validator.validate(new ValidationContext(100, 100));
    } catch (ValidationException e) {
      fail("FailureHandler should NOT have thrown an exception");
    }
  }

  /**
   * Test the validation for a sample import, positive case.
   *
   * @throws Exception
   */
  @Test
  public void testValidatorForImportTable() throws Exception {
    String[] types = {"INT NOT NULL PRIMARY KEY", "VARCHAR(32)", "VARCHAR(32)"};
    String[] insertVals = {"1", "'Bob'", "'sales'"};
    String validateLine = "1,Bob,sales";

    try {
      createTableWithColTypes(types, insertVals);

      verifyImport(validateLine, null);
      LOG.debug("Verified input line as " + validateLine + " -- ok!");
    } finally {
      dropTableIfExists(getTableName());
    }
  }
}
