// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed 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 com.google.devtools.common.options;

import com.google.devtools.common.options.OptionsParser.ConstructionException;
import java.util.Arrays;
import java.util.List;

/**
 * Interface for parsing options from a single options specification class.
 *
 * The {@link Options#parse(Class, String...)} method in this class has no clear
 * use case. Instead, use the {@link OptionsParser} class directly, as in this
 * code snippet:
 *
 * <pre>
 * OptionsParser parser = OptionsParser.newOptionsParser(FooOptions.class);
 * try {
 *   parser.parse(FooOptions.class, args);
 * } catch (OptionsParsingException e) {
 *   System.err.print("Error parsing options: " + e.getMessage());
 *   System.err.print(options.getUsage());
 *   System.exit(1);
 * }
 * FooOptions foo = parser.getOptions(FooOptions.class);
 * List&lt;String&gt; otherArguments = parser.getResidue();
 * </pre>
 *
 * Using this class in this case actually results in more code.
 *
 * @see OptionsParser for parsing options from multiple options specification classes.
 */
public class Options<O extends OptionsBase> {

  /**
   * Parse the options provided in args, given the specification in
   * optionsClass.
   */
  public static <O extends OptionsBase> Options<O> parse(Class<O> optionsClass, String... args)
      throws OptionsParsingException {
    OptionsParser parser = OptionsParser.newOptionsParser(optionsClass);
    parser.parse(OptionPriority.PriorityCategory.COMMAND_LINE, null, Arrays.asList(args));
    List<String> remainingArgs = parser.getResidue();
    return new Options<>(parser.getOptions(optionsClass), remainingArgs.toArray(new String[0]));
  }

  /**
   * A convenience function for use in main methods. Parses the command line parameters, and exits
   * upon error. Also, prints out the usage message if "--help" appears anywhere within {@code
   * args}.
   */
  public static <O extends OptionsBase> Options<O> parseAndExitUponError(
      Class<O> optionsClass, boolean allowResidue, String... args) {
    OptionsParser parser = null;
    try {
      parser = OptionsParser.newOptionsParser(optionsClass);
      parser.setAllowResidue(allowResidue);
    } catch (ConstructionException e) {
      System.err.println("Error constructing the options parser: " + e.getMessage());
      System.exit(2);
    }
    parser.parseAndExitUponError(args);
    List<String> remainingArgs = parser.getResidue();
    return new Options<>(parser.getOptions(optionsClass), remainingArgs.toArray(new String[0]));
  }

  /**
   * Returns an options object at its default values.  The returned object may
   * be freely modified by the caller, by assigning its fields.
   */
  public static <O extends OptionsBase> O getDefaults(Class<O> optionsClass) {
    try {
      return parse(optionsClass, new String[0]).getOptions();
    } catch (OptionsParsingException e) {
      String message = "Error while parsing defaults: " + e.getMessage();
      throw new AssertionError(message);
    }
  }

  /**
   * Returns a usage string (renders the help information, the defaults, and
   * of course the option names).
   */
  public static String getUsage(Class<? extends OptionsBase> optionsClass) {
    StringBuilder usage = new StringBuilder();
    OptionsUsage.getUsage(optionsClass, usage);
    return usage.toString();
  }

  private O options;
  private String[] remainingArgs;

  private Options(O options, String[] remainingArgs) {
    this.options = options;
    this.remainingArgs = remainingArgs;
  }

  /**
   * Returns an instance of options class O.
   */
  public O getOptions() {
    return options;
  }

  /**
   * Returns the arguments that we didn't parse.
   */
  public String[] getRemainingArgs() {
    return remainingArgs;
  }

}
