/*
 * 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.pirk.querier.wideskies;

import java.io.File;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.pirk.utils.SystemConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Class for parsing the command line options for the QuerierDriver
 */
public class QuerierCLI
{
  private static final Logger logger = LoggerFactory.getLogger(QuerierCLI.class);

  private Options cliOptions = null;
  private CommandLine commandLine = null;

  private static final String LOCALPROPFILE = "local.querier.properties";

  /**
   * Create and parse allowable options
   * 
   */
  public QuerierCLI(String[] args)
  {
    // Create the command line options
    cliOptions = createOptions();

    try
    {
      // Parse the command line options
      CommandLineParser parser = new GnuParser();
      commandLine = parser.parse(cliOptions, args, true);

      // if help option is selected, just print help text and exit
      if (hasOption("h"))
      {
        printHelp();
        System.exit(1);
      }

      // Parse and validate the options provided
      if (!parseOptions())
      {
        logger.info("The provided options are not valid");
        printHelp();
        System.exit(1);
      }
    } catch (Exception e)
    {
      e.printStackTrace();
      System.exit(1);
    }
  }

  /**
   * Determine if an option was provided by the user via the CLI
   * 
   * @param option
   *          - the option of interest
   * @return true if option was provided, false otherwise
   */
  public boolean hasOption(String option)
  {
    return commandLine.hasOption(option);
  }

  /**
   * Obtain the argument of the option provided by the user via the CLI
   * 
   * @param option
   *          - the option of interest
   * @return value of the argument of the option
   */
  public String getOptionValue(String option)
  {
    return commandLine.getOptionValue(option);
  }

  /**
   * Method to parse and validate the options provided
   * 
   * @return - true if valid, false otherwise
   */
  private boolean parseOptions()
  {
    boolean valid = true;

    // If we have a local.querier.properties file specified, load it
    if (hasOption(LOCALPROPFILE))
    {
      SystemConfiguration.loadPropsFromFile(new File(getOptionValue(LOCALPROPFILE)));
    }
    else
    {
      // Pull options, set as properties
      for (String prop : QuerierProps.PROPSLIST)
      {
        if (hasOption(prop))
        {
          SystemConfiguration.setProperty(prop, getOptionValue(prop));
        }
      }
    }

    // Validate properties
    valid = QuerierProps.validateQuerierProperties();

    return valid;
  }

  /**
   * Create the options available for the DistributedTestDriver
   * 
   * @return Apache's CLI Options object
   */
  private Options createOptions()
  {
    Options options = new Options();

    // help
    Option optionHelp = new Option("h", "help", false, "Print out the help documentation for this command line execution");
    optionHelp.setRequired(false);
    options.addOption(optionHelp);

    // local.querier.properties
    Option optionLocalPropFile = new Option("localPropFile", LOCALPROPFILE, true, "Optional local properties file");
    optionLocalPropFile.setRequired(false);
    optionLocalPropFile.setArgName(LOCALPROPFILE);
    optionLocalPropFile.setType(String.class);
    options.addOption(optionLocalPropFile);

    // ACTION
    Option optionACTION = new Option("a", QuerierProps.ACTION, true, "required - 'encrypt' or 'decrypt' -- The action performed by the QuerierDriver");
    optionACTION.setRequired(false);
    optionACTION.setArgName(QuerierProps.ACTION);
    optionACTION.setType(String.class);
    options.addOption(optionACTION);

    // INPUTFILE
    Option optionINPUTFILE = new Option("i", QuerierProps.INPUTFILE, true,
        "required - Fully qualified file containing input "
            + "-- \n The input is either: \n (1) For Encryption: A query file - Contains the query selectors, one per line; "
            + "the first line must be the query number \n OR \n (2) For Decryption: A response file - Contains the serialized Response object");
    optionINPUTFILE.setRequired(false);
    optionINPUTFILE.setArgName(QuerierProps.INPUTFILE);
    optionINPUTFILE.setType(String.class);
    options.addOption(optionINPUTFILE);

    // OUTPUTFILE
    Option optionOUTPUTFILE = new Option("o", QuerierProps.OUTPUTFILE, true,
        "required - Fully qualified file for the result output. "
            + "\n The output file specifies either: \n (1) For encryption: \n \t (a) A file to contain the serialized Querier object named: " + "<outputFile>-"
            + QuerierConst.QUERIER_FILETAG + "  AND \n \t " + "(b) A file to contain the serialized Query object named: <outputFile>-"
            + QuerierConst.QUERY_FILETAG + "\n " + "OR \n (2) A file to contain the decryption results where each line is where each line "
            + "corresponds to one hit and is a JSON object with the schema QuerySchema");
    optionOUTPUTFILE.setRequired(false);
    optionOUTPUTFILE.setArgName(QuerierProps.OUTPUTFILE);
    optionOUTPUTFILE.setType(String.class);
    options.addOption(optionOUTPUTFILE);

    // NUMTHREADS
    Option optionNUMTHREADS = new Option("nt", QuerierProps.NUMTHREADS, true, "required -- Number of threads to use for encryption/decryption");
    optionNUMTHREADS.setRequired(false);
    optionNUMTHREADS.setArgName(QuerierProps.NUMTHREADS);
    optionNUMTHREADS.setType(String.class);
    options.addOption(optionNUMTHREADS);

    // DATASCHEMAS
    Option optionDataSchemas = new Option("ds", QuerierProps.DATASCHEMAS, true, "optional -- Comma separated list of data schema file names");
    optionDataSchemas.setRequired(false);
    optionDataSchemas.setArgName(QuerierProps.DATASCHEMAS);
    optionDataSchemas.setType(String.class);
    options.addOption(optionDataSchemas);

    // QUERYSCHEMAS
    Option optionQuerySchemas = new Option("qs", QuerierProps.QUERYSCHEMAS, true, "optional -- Comma separated list of query schema file names");
    optionQuerySchemas.setRequired(false);
    optionQuerySchemas.setArgName(QuerierProps.QUERYSCHEMAS);
    optionQuerySchemas.setType(String.class);
    options.addOption(optionQuerySchemas);

    // TYPE
    Option optionTYPE = new Option("qt", QuerierProps.QUERYTYPE, true,
        "required for encryption -- Type of the query as defined " + "in the 'schemaName' tag of the corresponding query schema file");
    optionTYPE.setRequired(false);
    optionTYPE.setArgName(QuerierProps.QUERYTYPE);
    optionTYPE.setType(String.class);
    options.addOption(optionTYPE);

    // HASHBITSIZE
    Option optionHASHBITSIZE = new Option("hb", QuerierProps.HASHBITSIZE, true, "required -- Bit size of keyed hash");
    optionHASHBITSIZE.setRequired(false);
    optionHASHBITSIZE.setArgName(QuerierProps.HASHBITSIZE);
    optionHASHBITSIZE.setType(String.class);
    options.addOption(optionHASHBITSIZE);

    // HASHKEY
    Option optionHASHKEY = new Option("hk", QuerierProps.HASHKEY, true, "required for encryption -- String key for the keyed hash functionality");
    optionHASHKEY.setRequired(false);
    optionHASHKEY.setArgName(QuerierProps.HASHKEY);
    optionHASHKEY.setType(String.class);
    options.addOption(optionHASHKEY);

    // DATAPARTITIONSIZE
    Option optionDATAPARTITIONSIZE = new Option("dps", QuerierProps.DATAPARTITIONSIZE, true,
        "required for encryption -- Partition bit size in data partitioning");
    optionDATAPARTITIONSIZE.setRequired(false);
    optionDATAPARTITIONSIZE.setArgName(QuerierProps.DATAPARTITIONSIZE);
    optionDATAPARTITIONSIZE.setType(String.class);
    options.addOption(optionDATAPARTITIONSIZE);

    // PAILLIERBITSIZE
    Option optionPAILLIERBITSIZE = new Option("pbs", QuerierProps.PAILLIERBITSIZE, true, "required for encryption -- Paillier modulus size N");
    optionPAILLIERBITSIZE.setRequired(false);
    optionPAILLIERBITSIZE.setArgName(QuerierProps.PAILLIERBITSIZE);
    optionPAILLIERBITSIZE.setType(String.class);
    options.addOption(optionPAILLIERBITSIZE);

    // CERTAINTY
    Option optionCERTAINTY = new Option("c", QuerierProps.CERTAINTY, true,
        "required for encryption -- Certainty of prime generation for Paillier -- must  be greater than or " + "equal to "
            + SystemConfiguration.getProperty("pir.primeCertainty") + "");
    optionCERTAINTY.setRequired(false);
    optionCERTAINTY.setArgName(QuerierProps.CERTAINTY);
    optionCERTAINTY.setType(String.class);
    options.addOption(optionCERTAINTY);

    // BITSET
    Option optionBITSET = new Option("b", QuerierProps.BITSET, true, "required for encryption -- Ensure that this bit position is set in the "
        + "Paillier modulus (will generate Paillier moduli until finding one in which this bit is set)");
    optionBITSET.setRequired(false);
    optionBITSET.setArgName(QuerierProps.BITSET);
    optionBITSET.setType(String.class);
    options.addOption(optionBITSET);

    // embedSelector
    Option optionEmbedSelector = new Option("embed", QuerierProps.EMBEDSELECTOR, true,
        "required for encryption -- 'true' or 'false' - Whether or not to embed " + "the selector in the results to reduce false positives");
    optionEmbedSelector.setRequired(false);
    optionEmbedSelector.setArgName(QuerierProps.EMBEDSELECTOR);
    optionEmbedSelector.setType(String.class);
    options.addOption(optionEmbedSelector);

    // useMemLookupTable
    Option optionUseMemLookupTable = new Option("mlu", QuerierProps.USEMEMLOOKUPTABLE, true,
        "required for encryption -- 'true' or 'false' - Whether or not to generate and use "
            + "an in memory modular exponentation lookup table - only for standalone/testing right now...");
    optionUseMemLookupTable.setRequired(false);
    optionUseMemLookupTable.setArgName(QuerierProps.USEMEMLOOKUPTABLE);
    optionUseMemLookupTable.setType(String.class);
    options.addOption(optionUseMemLookupTable);

    // useHDFSLookupTable
    Option optionUseHDFSLookupTable = new Option("lu", QuerierProps.USEHDFSLOOKUPTABLE, true,
        "required for encryption -- 'true' or 'false' -- Whether or not to generate and use " + "a hdfs modular exponentation lookup table");
    optionUseHDFSLookupTable.setRequired(false);
    optionUseHDFSLookupTable.setArgName(QuerierProps.USEHDFSLOOKUPTABLE);
    optionUseHDFSLookupTable.setType(String.class);
    options.addOption(optionUseHDFSLookupTable);

    // QUERIERFILE
    Option optionQUERIERFILE = new Option("qf", QuerierProps.QUERIERFILE, true,
        "required for decryption -- Fully qualified file containing the serialized Querier object");
    optionQUERIERFILE.setRequired(false);
    optionQUERIERFILE.setArgName(QuerierProps.QUERIERFILE);
    optionQUERIERFILE.setType(String.class);
    options.addOption(optionQUERIERFILE);

    // embedQuerySchema
    Option optionEMBEDQUERYSCHEMA = new Option("embedQS", QuerierProps.EMBEDQUERYSCHEMA, true,
        "optional (defaults to false) -- Whether or not to embed the QuerySchema in the Query (via QueryInfo)");
    optionEMBEDQUERYSCHEMA.setRequired(false);
    optionEMBEDQUERYSCHEMA.setArgName(QuerierProps.EMBEDQUERYSCHEMA);
    optionEMBEDQUERYSCHEMA.setType(String.class);
    options.addOption(optionEMBEDQUERYSCHEMA);

    // SR_ALGORITHM
    Option optionSR_ALGORITHM = new Option("srAlg", QuerierProps.SR_ALGORITHM, true, "optional - specify the SecureRandom algorithm, defaults to NativePRNG");
    optionSR_ALGORITHM.setRequired(false);
    optionSR_ALGORITHM.setArgName(QuerierProps.SR_ALGORITHM);
    optionSR_ALGORITHM.setType(String.class);
    options.addOption(optionSR_ALGORITHM);

    // SR_PROVIDERS
    Option optionSR_PROVIDER = new Option("srProvider", QuerierProps.SR_PROVIDER, true, "optional - specify the SecureRandom provider, defaults to SUN");
    optionSR_PROVIDER.setRequired(false);
    optionSR_PROVIDER.setArgName(QuerierProps.SR_PROVIDER);
    optionSR_PROVIDER.setType(String.class);
    options.addOption(optionSR_PROVIDER);

    return options;
  }

  /**
   * Prints out the help message
   */
  private void printHelp()
  {
    HelpFormatter formatter = new HelpFormatter();
    formatter.setWidth(140);
    formatter.printHelp("QuerierDriver", cliOptions);
  }
}
