/* ****************************************************************************
 * Copyright 2013-2016 VMware, Inc. All rights reserved.
 * ****************************************************************************/

package com.vmware.samples.recovery;

import java.net.MalformedURLException;
import java.net.URL;


/**
 * This is a container object for configurations that are relevant to the
 * Recovery Plan sample application.
 */
/*package*/ final class Options
   extends com.vmware.samples.srm.Options {

   /** Only display results for this recovery plan. */
   public final String _planName;

   /**
    * Construct a container for the configuration that pertains specifically
    * to this sample application.
    *
    * @param url        The URL used to contact the SRM API.
    * @param userName   SRM user name.
    * @param password   SRM password for {@link #_userName}.
    * @param planName   Only display results for this recovery plan.
    * @param ignoreCert The user has requested to ignore SSL certificates in
    *    SRM connections.
    */
   /*package*/ Options(
      final URL     url,
      final String  userName,
      final String  password,
      final String  planName,
      final boolean ignoreCert) {

      super(url, userName, password, ignoreCert);
      _planName = planName;
   }

   /**
    * Construct the options encapsulation, performing a (quick-and-dirty) parse
    * of the command-line arguments.
    *
    * @param args The tokenized command-line parameters.
    * @throws InvalidCliArgumentException if the command-line input is incorrect
    *    for any reason.
    * @throws ShowHelpThrowable if a "--help" parameter has been specified.
    *    This halts the command-line processing and invalidates the Options
    *    instance.
    */
   /*package*/ static Options parseOptions(final String[] args)
      throws Options.InvalidCliArgumentException,
             Options.ShowHelpThrowable {

      // Temporary data to populate final member data
      boolean ignoreCert = false;
      String  password = null;
      String  planName = null;
      int     portNumber = 9086;
      String  protocol = "https";
      String  server = null;
      String  servicePath = "/vcdr/extapi/sdk";
      String  userName = null;
      URL     url = null;

      for (int i = 0; i < args.length; ++i) {

         // Parameters without arguments:
         if (args[i].equals("--help")) {
            throw new ShowHelpThrowable();
         } else if (args[i].equals("--ignorecert")) {
            ignoreCert = true;
         }

         // Parameters that require arguments:
         else if (args[i].equals("--url")) {
            if (++i == args.length) {
               throw new InvalidCliArgumentException(
                  "--url option requires an argument");
            }
            try {
               url = new URL(args[i]);
            } catch (MalformedURLException mue) {
               throw new InvalidCliArgumentException(
                  "Specified URL is malformed -- " + mue.getMessage(), mue);
            }
         } else if (args[i].equals("--planname")) {
            if (++i == args.length) {
               throw new InvalidCliArgumentException(
                  "--planname option requires an argument");
            }
            planName = args[i];
         } else if (args[i].equals("--username")) {
            if (++i == args.length) {
               throw new InvalidCliArgumentException(
                  "--username option requires an argument");
            }
            userName = args[i];
         } else if (args[i].equals("--password")) {
            if (++i == args.length) {
               throw new InvalidCliArgumentException(
                  "--password option requires an argument");
            }
            password = args[i];
         } else if (args[i].equals("--protocol")) {
            if (++i == args.length) {
               throw new InvalidCliArgumentException(
                  "--protocol option requires an argument");
            }
            protocol = args[i];
         } else if (args[i].equals("--server")) {
            if (++i == args.length) {
               throw new InvalidCliArgumentException(
                  "--server option requires an argument");
            }
            server = args[i];
         } else if (args[i].equals("--portnumber")) {
            if (++i == args.length) {
               throw new InvalidCliArgumentException(
                  "--portnumber option requires an argument");
            }
            try {
               portNumber = Integer.parseInt(args[i]);
            } catch (NumberFormatException nfe) {
               throw new InvalidCliArgumentException(
                  "Invalid port number", nfe);
            }
         } else if (args[i].equals("--servicepath")) {
            if (++i == args.length) {
               throw new InvalidCliArgumentException(
                  "--servicepath option requires an argument");
            }
            if (!args[i].isEmpty()) {
               if ('/' != args[i].charAt(0)) {
                  servicePath = "/" + args[i];
               } else {
                  servicePath = args[i];
               }
            }
         }

         // Unknown command-line argument:
         else {
            throw new InvalidCliArgumentException(
               "Invalid argument -- \"" + args[i] + "\"");
         }
      }

      if ((userName == null) || (password == null)) {
         throw new InvalidCliArgumentException(
            "User and password are required");
      }

      if (url == null) {
         StringBuffer sb = new StringBuffer();
         sb.append(protocol);
         sb.append("://");
         sb.append(server);
         if (portNumber > 0) {
            sb.append(':');
            sb.append(portNumber);
         } else if (portNumber < 0) {
            throw new InvalidCliArgumentException("Invalid port number");
         }
         sb.append(servicePath);

         try {
            url = new URL(sb.toString());
         } catch (MalformedURLException mue) {
            throw new InvalidCliArgumentException(
               "Specified URL is malformed -- " + mue.getMessage(), mue);
         }
      }

      return new Options(url, userName, password, planName, ignoreCert);
   }

   /**
    * Prints a helpful usage message to the console.
    * @param progName The name of the executable being run.
    */
   /*package*/ static void printHelp(final String progName) {

      System.out.println(
            "Usage: " + progName +
            " --url <srm-URL> --username <un> --password <pass>");
      System.out.println(
            "Usage: " + progName +
            " --server <srm-host> [host-options] \\");
      System.out.println(
            " --username <un> --password <pass> [options]");

      System.out.println();
      System.out.println("Required Options:");
      System.out.println("  --username <un>    The SRM administrator account.");
      System.out.println("  --password <pass>  Password for <un>.");

      System.out.println();
      System.out.println("[options]");
      System.out.println(
         "  --ignorecert       Ignore SSL certificate during connection.");
      System.out.println(
         "  --planname <name>  Returns only results about the specified plan.");
      System.out.println(
         "  --help             Prints this help screen.");

      System.out.println();
      System.out.println("[host-options]");
      System.out.println(
         "  --protocol <prot>  SRM protocol (default: https).");
      System.out.println(
         "  --portnumber <###> SRM API port number (default: 9086).");
      System.out.println(
         "  --servicepath <p>  Custom URL path to the SRM API.");
      System.out.println(
         "  --server <server>  The host name or IP of SRM.");
   }
}
