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

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.sqoop.testcategories.sqooptest.UnitTest;
import org.apache.sqoop.util.OptionsFileUtil;
import org.junit.Assert;

import org.apache.sqoop.Sqoop;
import org.junit.Test;
import org.junit.experimental.categories.Category;

/**
 * Tests various options file loading scenarios.
 */
@Category(UnitTest.class)
public class TestOptionsFileExpansion {

  /**
   * Text from options file 1. Each string represents a new line.
   */
  private static final String[] OPTIONS_FILE_TEXT1 = new String[] {
    "--foo",
    "-bar",
    "--",
    "--XYZ",
  };

  /**
   * Expected options parsed out from options file 1.
   */
  private static final String[] OPTIONS_FILE_TEXT1_OUTPUT = new String[] {
    "--foo",
    "-bar",
    "--",
    "--XYZ",
  };

  /**
   * Text for options file 2. Each string represents a new line. This
   * contains empty lines, comments and optinos that extend to multiple lines.
   */
  private static final String[] OPTIONS_FILE_TEXT2 = new String[] {
    "--archives",
    "tools.jar,archive.jar,test.jar,\\",
    "ldap.jar,sasl.jar",
    "--connect",
    "jdbc:jdbcspy:localhost:1521:test",
    "--username",
    "superman",
    "--password",
    "",
    "# Ironic password.",
    "# No one will ever guess.",
    "kryptonite",
  };

  /**
   * Expected options parsed out from file 2.
   */
  private static final String[] OPTIONS_FILE_TEXT2_OUTPUT = new String[] {
    "--archives",
    "tools.jar,archive.jar,test.jar,ldap.jar,sasl.jar",
    "--connect",
    "jdbc:jdbcspy:localhost:1521:test",
    "--username",
    "superman",
    "--password",
    "kryptonite",
  };

  /**
   * Text for options file 4. This contains options that represent empty
   * strings or strings that have leading and trailing spaces.
   */
  private static final String[] OPTIONS_FILE_TEXT3 = new String[] {
    "-",
    "\"     leading spaces\"",
    "'        leading and trailing spaces    '",
    "\"\"",
    "''",
  };

  /**
   * Expected options parsed out from file 3.
   */
  private static final String[] OPTIONS_FILE_TEXT3_OUTPUT = new String[] {
    "-",
    "     leading spaces",
    "        leading and trailing spaces    ",
    "",
    "",
  };

  /**
   * Text for options file 4. This file has an invalid entry in the last line
   * which will cause it to fail to load.
   */
  private static final String[] OPTIONS_FILE_TEXT4 = new String[] {
    "--abcd",
    "--efgh",
    "# foo",
    "# bar",
    "XYZ\\",
  };

  /**
   * Text for options file 5. This file has an invalid entry in the second line
   * where there is a starting single quote character that is not terminating.
   */
  private static final String[] OPTIONS_FILE_TEXT5 = new String[] {
    "-abcd",
    "\'",
    "--foo",
  };

  /**
   * Text for options file 6. This file has an invalid entry in the second line
   * where a quoted string extends into the following line.
   */
  private static final String[] OPTIONS_FILE_TEXT6 = new String[] {
    "--abcd",
    "' the quick brown fox \\",
    "jumped over the lazy dog'",
    "--efgh",
  };

  @Test
  public void testOptionsFiles() throws Exception {
    checkOptionsFile(OPTIONS_FILE_TEXT1, OPTIONS_FILE_TEXT1_OUTPUT);
    checkOptionsFile(OPTIONS_FILE_TEXT2, OPTIONS_FILE_TEXT2_OUTPUT);
    checkOptionsFile(OPTIONS_FILE_TEXT3, OPTIONS_FILE_TEXT3_OUTPUT);
  }

  @Test
  public void testInvalidOptionsFile() {
    checkInvalidOptionsFile(OPTIONS_FILE_TEXT4);
    checkInvalidOptionsFile(OPTIONS_FILE_TEXT5);
  }

  @Test
  public void testMultilineQuotedText() {
    try {
      checkOptionsFile(OPTIONS_FILE_TEXT6, new String[] {});
      Assert.assertTrue(false);
    } catch (Exception ex) {
      Assert.assertTrue(
          ex.getMessage().startsWith("Multiline quoted strings not supported"));
    }
  }

  @Test
  public void testValidFreeFormQueryNoQuotes() throws Exception {
    String[] input = new String[]{
        "--query",
        "SELECT * FROM table",
    };

    String[] output = new String[] {
        "--query",
        "SELECT * FROM table",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testValidFreeFormQuerySingleQuotesStartAndEnd() throws Exception {
    String[] input = new String[]{
        "--query",
        "'SELECT * FROM table'",
    };

    String[] output = new String[]{
        "--query",
        "SELECT * FROM table",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testValidFreeFormQueryDoubleQuotesStartAndEnd() throws Exception {
    String[] input = new String[]{
        "--query",
        "\"SELECT * FROM table\"",
    };

    String[] output = new String[]{
        "--query",
        "SELECT * FROM table",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testValidFreeFormQuerySingleQuotesInWhere() throws Exception {
    String[] input = new String[]{
        "--query",
        "SELECT * FROM table WHERE a = '1'",
    };

    String[] output = new String[]{
        "--query",
        "SELECT * FROM table WHERE a = '1'",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testValidFreeFormQuerySingleAndDoubleQuotesInWhere() throws Exception {
    String[] input = new String[] {
        "--query",
        "SELECT * FROM table WHERE a = '1' AND b = \"testing\"",
    };

    String[] output = new String[] {
        "--query",
        "SELECT * FROM table WHERE a = '1' AND b = \"testing\"",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testValidFreeFormQueryQuotesInTableNameAndColumnName() throws Exception {
    String[] input = new String[] {
        "--query",
        "select * from `test\"test`  where `c'c`  = 'a'",
    };

    String[] output = new String[] {
        "--query",
        "select * from `test\"test`  where `c'c`  = 'a'",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testValidFreeFormQueryQuotesInTableNameAndColumnName2() throws Exception {
    String[] input = new String[] {
        "--query",
        "select * from `test\"test`  where `c'c`  = 'a\"'",
    };

    String[] output = new String[] {
        "--query",
        "select * from `test\"test`  where `c'c`  = 'a\"'",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testValidFreeFormQueryQuotesInTableNameAndColumnName3() throws Exception {
    String[] input = new String[] {
        "--query",
        "select * from `test\"test`  where `c'c`  = \"\"",
    };

    String[] output = new String[] {
        "--query",
        "select * from `test\"test`  where `c'c`  = \"\"",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testValidFreeFormQueryQuotesInTableNameAndColumnName4() throws Exception {
    String[] input = new String[] {
        "--query",
        "select * from test  where a  = \"\\\"\"",
    };

    String[] output = new String[] {
        "--query",
        "select * from test  where a  = \"\\\"\"",
    };

    checkOptionsFile(input, output);
  }

  @Test
  public void testInvalidFreeFormQueryEndingSingleQuoteOnly() throws Exception {
    String[] input = new String[]{
        "--query",
        "SELECT * FROM table'",
    };

    checkInvalidOptionsFile(input);
  }

  @Test
  public void testInvalidFreeFormQuerySingleQuoteStartDoubleQuoteEnd() throws Exception {

    String[] input = new String[]{
        "--query",
        "'SELECT * FROM table\"",
    };

    checkInvalidOptionsFile(input);
  }

  private void checkInvalidOptionsFile(String[] fileContents) {
    try {
      checkOptionsFile(fileContents, new String[] {});
      Assert.assertTrue(false);
    } catch (Exception ex) {
      Assert.assertTrue(ex.getMessage().startsWith("Malformed option"));
    }
  }

  private void checkOptionsFile(String[] fileContent, String[] expectedOptions)
    throws Exception {
    String[] prefix0 = new String[] { };
    String[] suffix0 = new String[] { };

    checkOutput(prefix0, suffix0, fileContent, expectedOptions);

    String[] prefix1 = new String[] { "--nomnom" };
    String[] suffix1 = new String[] { };

    checkOutput(prefix1, suffix1,
        fileContent, expectedOptions);

    String[] prefix2 = new String[] { };
    String[] suffix2 = new String[] { "yIkes" };

    checkOutput(prefix2, suffix2,
        fileContent, expectedOptions);

    String[] prefix3 = new String[] { "foo", "bar" };
    String[] suffix3 = new String[] { "xyz", "abc" };

    checkOutput(prefix3, suffix3,
        fileContent, expectedOptions);
  }


  /**
   * Uses the given prefix and suffix to create the original args array which
   * contains two entries between the prefix and suffix entries that specify
   * the options file. The options file is dynamically created using the
   * contents of the third array - fileContent. Once this is expanded, the
   * expanded arguments are compared to see if they are same as prefix entries
   * followed by parsed arguments from the options file, followed by suffix
   * entries.
   * @param prefix
   * @param suffix
   * @param fileContent
   * @param expectedContent
   * @throws Exception
   */
  private void checkOutput(String[] prefix, String[] suffix,
      String[] fileContent, String[] expectedContent) throws Exception {

    String[] args = new String[prefix.length + 2 + suffix.length];

    for (int i = 0; i < prefix.length; i++) {
      args[i] = prefix[i];
    }
    args[prefix.length] = Sqoop.SQOOP_OPTIONS_FILE_SPECIFIER;
    args[prefix.length + 1] =  createOptionsFile(fileContent);
    for (int j = 0; j < suffix.length; j++) {
      args[j + 2 + prefix.length] = suffix[j];
    }

    String[] expandedArgs = OptionsFileUtil.expandArguments(args);

    assertSame(prefix, expectedContent, suffix, expandedArgs);

  }

  private void assertSame(String[] prefix, String[] content, String[] suffix,
      String[] actual) {
    Assert.assertTrue(prefix.length + content.length + suffix.length
        == actual.length);

    for (int i = 0; i < prefix.length; i++) {
      Assert.assertTrue(actual[i].equals(prefix[i]));
    }

    for (int i = 0; i < content.length; i++) {
      Assert.assertTrue(actual[i + prefix.length].equals(content[i]));
    }

    for (int i = 0; i < suffix.length; i++) {
      Assert.assertTrue(actual[i + prefix.length + content.length].equals(
          suffix[i]));
    }
  }

  private String createOptionsFile(String[] data) throws Exception {
    File file = File.createTempFile("options", ".opf");
    file.deleteOnExit();

    BufferedWriter writer = null;
    try {
      writer = new BufferedWriter(new FileWriter(file));
      for (String datum : data) {
        writer.write(datum);
        writer.newLine();
      }
    } finally {
      if (writer != null) {
        try {
          writer.close();
        } catch (IOException ex) {
          // No handling required
        }
      }
    }

    return file.getAbsolutePath();
  }
}
