/**
 * 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.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.cloudera.sqoop.Sqoop;

/**
 * Provides utility functions to read in options file. An options file is a
 * regular text file with each line specifying a separate option. An option
 * may continue into a following line by using a back-slash separator character
 * at the end of the non-terminating line. Options file also allow empty lines
 * and comment lines which are disregarded. Comment lines must begin with the
 * hash character as the first character. Leading and trailing white-spaces are
 * ignored for any options read from the Options file.
 */
public final class OptionsFileUtil {

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

  private OptionsFileUtil() { }

  /**
   * Expands any options file that may be present in the given set of arguments.
   *
   * @param args the given arguments
   * @return a new string array that contains the expanded arguments.
   * @throws Exception
   */
  public static String[] expandArguments(String[] args) throws Exception {
    List<String> options = new ArrayList<String>();

    for (int i = 0; i < args.length; i++) {
      if (args[i].equals(Sqoop.SQOOP_OPTIONS_FILE_SPECIFIER)) {
        if (i == args.length - 1) {
          throw new Exception("Missing options file");
        }

        String fileName = args[++i];
        File optionsFile = new File(fileName);
        BufferedReader reader = null;
        StringBuilder buffer = new StringBuilder();
        try {
          reader = new BufferedReader(new FileReader(optionsFile));
          String nextLine = null;
          while ((nextLine = reader.readLine()) != null) {
            nextLine = nextLine.trim();
            if (nextLine.length() == 0 || nextLine.startsWith("#")) {
              // empty line or comment
              continue;
            }

            buffer.append(nextLine);
            if (nextLine.endsWith("\\")) {
              if (buffer.charAt(0) == '\'' || buffer.charAt(0) == '"') {
                throw new Exception(
                    "Multiline quoted strings not supported in file("
                      + fileName + "): " + buffer.toString());
              }
              // Remove the trailing back-slash and continue
              buffer.deleteCharAt(buffer.length()  - 1);
            } else {
              // The buffer contains a full option
              options.add(
                  removeQuotesEncolosingOption(fileName, buffer.toString()));
              buffer.delete(0, buffer.length());
            }
          }

          // Assert that the buffer is empty
          if (buffer.length() != 0) {
            throw new Exception("Malformed option in options file("
                + fileName + "): " + buffer.toString());
          }
        } catch (IOException ex) {
          throw new Exception("Unable to read options file: " + fileName, ex);
        } finally {
          if (reader != null) {
            try {
              reader.close();
            } catch (IOException ex) {
              LOG.info("Exception while closing reader", ex);
            }
          }
        }
      } else {
        // Regular option. Parse it and put it on the appropriate list
        options.add(args[i]);
      }
    }

    return options.toArray(new String[options.size()]);
  }

  /**
   * Removes the surrounding quote characters as needed. It first attempts to
   * remove surrounding double quotes. If successful, the resultant string is
   * returned. If no surrounding double quotes are found, it attempts to remove
   * surrounding single quote characters. If successful, the resultant string
   * is returned. If not the original string is returnred.
   * @param fileName
   * @param option
   * @return
   * @throws Exception
   */
  private static String removeQuotesEncolosingOption(
      String fileName, String option) throws Exception {

    // Attempt to remove double quotes. If successful, return.
    String option1 = removeQuoteCharactersIfNecessary(fileName, option, '"');
    if (!option1.equals(option)) {
      // Quotes were successfully removed
      return option1;
    }

    // Attempt to remove single quotes.
    return removeQuoteCharactersIfNecessary(fileName, option, '\'');
  }

  /**
   * Removes the surrounding quote characters from the given string. The quotes
   * are identified by the quote parameter, the given string by option. The
   * fileName parameter is used for raising exceptions with relevant message.
   * @param fileName String The name of the file that contains sqoop options
   * @param option String the actual options in the options file
   * @param quote char The quote that we need to validate on, either single or double quotes
   * @return String The validated options string
   * @throws Exception
   */
  private static String removeQuoteCharactersIfNecessary(String fileName,
      String option, char quote) throws Exception {
    boolean startingQuote = (option.charAt(0) == quote);
    boolean endingQuote = (option.charAt(option.length() - 1) == quote);

    if (startingQuote && endingQuote) {
      if (option.length() == 1) {
        throw new Exception("Malformed option in options file("
            + fileName + "): " + option);
      }
      return option.substring(1, option.length() - 1);
    }

    if (startingQuote || endingQuote) {
      // Regular expression looks like below:
      // .*=\s*".*"$ OR .*=\s*'.*'$
      // it tries to match the following:
      // .... column_name = "values" OR .... column_name = 'values'
      // so that the query like:
      // SELECT * FROM table WHERE column = "values"
      // is valid even though it ends with double quote but no starting double quote
      if (!Pattern.matches(".*=\\s*"+quote+".*"+quote+"$", option)) {
        throw new Exception("Malformed option in options file("
            + fileName + "): " + option);
      }
    }

    return option;
  }
}
